18

I would like to turn off HttpOnly sessions which I believe are default for Spring Boot. How would I turn off HttpOnly on spring boot?

I currently have code such as:

@RequestMapping(value = "/stuff", method = GET)
public @ResponseBody
myObject doStuff(HttpSession session)
{
        session.setAttribute("foo", "bar");
        return  new MyObject();
}

This returns a response header on the HTTP call:

Set-Cookie: JSESSIONID=D14846D9767B6404F1FB4B013AB66FB3; Path=/; HttpOnly 

Note the HttpOnly flag. I would like to turn that off. How do I do so?

Side note: Yes I know that httpOnly is a security feature and by turning it off allows javascript to access my cookie i.e. XSS.

Also, I do not have any configuration other than default.

@ComponentScan
@EnableAutoConfiguration
public class WebApplication {

    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(WebApplication.class);
        app.run(args);
    }
}
Nick Humrich
  • 14,905
  • 8
  • 62
  • 85

4 Answers4

15

Another alternative to the accepted answer that fits into spring boot is overriding the customize method of your EmbeddedServletContainerCustomizer.

First, implement the interface:

@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application implements EmbeddedServletContainerCustomizer

Then add an override for the customize method:

@Override
public void customize(final ConfigurableEmbeddedServletContainer container)
{
    ((TomcatEmbeddedServletContainerFactory) container).addContextCustomizers(new TomcatContextCustomizer()
    {
        @Override
        public void customize(Context context)
        {
            context.setUseHttpOnly(false);
        }
    });
}

Incidentally, I found that the httpOnly wasn't being set at all for me .. so I had to use this method to turn httpOnly on (obviously my setting above is 'true').

You can also use this method to adjust other things in tomcat, such as turning on gzip for json and expanding the max http headersize (in the case of kerberos authentication I needed to do this):

((TomcatEmbeddedServletContainerFactory) container).addConnectorCustomizers(new TomcatConnectorCustomizer()
{
    @Override
    public void customize(final Connector connector)
    {
        AbstractHttp11Protocol httpProtocol = (AbstractHttp11Protocol) connector.getProtocolHandler();
        httpProtocol.setMaxHttpHeaderSize(65536);
        httpProtocol.setCompression("on");
        httpProtocol.setCompressionMinSize(256);
        String mimeTypes = httpProtocol.getCompressableMimeTypes();
        String mimeTypesWithJson = mimeTypes + "," + MediaType.APPLICATION_JSON_VALUE;
        httpProtocol.setCompressableMimeTypes(mimeTypesWithJson);
    }
});
JimB
  • 1,143
  • 1
  • 12
  • 18
  • 2
    You actually answered two of my problems in one answer without you even knowing what my other problem was. Kudos – Nick Humrich Jun 13 '14 at 19:52
  • needed to set "secure" flag for session cookies.. `connector.setSecure(true);` worked for me – Vivek Sethi Feb 10 '16 at 15:57
  • 1
    FYI a lot of the above can be done with properties files in current versions of spring boot (v1.3+). [compression](https://docs.spring.io/spring-boot/docs/current/reference/html/howto-embedded-servlet-containers.html#how-to-enable-http-response-compression) and [full set of properties you can set](https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html) – JimB Mar 17 '16 at 11:50
  • 1
    @JimB - yes, there is property for http-only, but setting it to 'false' or leaving empty doesnt remove HttpOnly flag. Something is overriding it probably. But your solution works, thx! – hi_my_name_is Jan 18 '17 at 09:45
11
server.servlet.session.cookie.http-only=false 

(Property updated)

Reference https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html

double-beep
  • 5,031
  • 17
  • 33
  • 41
user2082512
  • 111
  • 1
  • 3
  • Thanks for the info. I just tried this on my Spring Boot app and it isn't working? JESSIONID is still set with HttpOnly. I wondered if you had any ideas how to debug or workaround? – paj28 Jan 13 '20 at 09:19
6

At least on Spring Boot >= 1.4, it's even easier, just use the following property:

server.servlet.session.cookie.http-only= # "HttpOnly" flag for the session cookie. configuration property.

as documented in the official documentation.

Community
  • 1
  • 1
Enrico M. Crisostomo
  • 1,653
  • 1
  • 17
  • 26
5

Tomcat has a context attribute named useHttpOnly which checks:

Should the HttpOnly flag be set on session cookies to prevent client side script from accessing the session ID? Defaults to true.

So you need to set it to false. The configuration linked applies to non-embedded Tomcat servers. We need to find a way to do it with embedded Tomcat.

Here's how you do it. You declare a @Bean method for adding a EmbeddedServletContainerFactory to the context. You configure the returned TomcatEmbeddedServletContainerFactory by specifying a TomcatContextCustomizer which configures the appropriate property.

@Bean
public EmbeddedServletContainerFactory servletContainer() {
    TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
    factory.setTomcatContextCustomizers(Arrays.asList(new CustomCustomizer()));
    return factory;
}

static class CustomCustomizer implements TomcatContextCustomizer {
    @Override
    public void customize(Context context) {
        context.setUseHttpOnly(false);
    }
}

This solution works because you are using Tomcat. With different Servlet containers, the solution would be different.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724