SameSite cookie in Java application
If you don't wanna update all your code, you can also achieve same by one line config using Apache or Nginx configuration(or any other HTTP server/proxy that you are using)
1 Setting SameSite cookies using Apache configuration
You can add the following line to your Apache configuration
Header always edit Set-Cookie (.*) "$1; SameSite=Lax"
and this will update all your cookies with SameSite=Lax
flag
See more here: https://blog.giantgeek.com/?p=1872
2 Setting SameSite cookies using Nginx configuration
location / {
# your usual config ...
# hack, set all cookies to secure, httponly and samesite (strict or lax)
proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict";
}
Same here, this also will update all your cookies with SameSite=Lax
flag
See more here: https://serverfault.com/questions/849888/add-samesite-to-cookies-using-nginx-as-reverse-proxy
As of today (24.01.20) servlet-api
does not let to set sameSite
attribute to the cookie. BTW there is an ongoing ticket (LINK) which will release a new (5.0 or 5.1 servlet-api
).
Option 1: You are not in a hurry and can wait for servlet-api
version, where Cookie
class and SessionCookieConfig
class have dedicated methods to set sameSite
attribute.
Option 2: You are using an old version of servlet-api
(e.g. 3.1), consequently old version of Tomcat (e.g. I am having current situation now). It means even when community releases servlet-api
with sameSite
support, you can not immediately update you version, because it can be too risky to update couple of major versions.
In this case we have found a solution.
There is a Cookie Processor Component
LINK in Tomcat, which
The CookieProcessor element represents the component that parses received cookie headers into javax.servlet.http.Cookie objects accessible through HttpServletRequest.getCookies() and converts javax.servlet.http.Cookie objects added to the response through HttpServletResponse.addCookie() to the HTTP headers returned to the client.
The usage of this processor is quite straight forward. Inside of context.xml:
<Context>
...
<CookieProcessor sameSiteCookies="none"/>
</Context>
In this case default implementation of processor is used (org.apache.tomcat.util.http.Rfc6265CookieProcessor
), but you can specify any other within an CookieProcessor
attribute className
.
If you happen to use Spring Framework you can take advantage of ResponseCookie class. Ex:
final ResponseCookie responseCookie = ResponseCookie
.from("<my-cookie-name>", "<my-cookie-value-here>")
.secure(true)
.httpOnly(true)
.path("/auth")
.maxAge(12345)
.sameSite("Lax")
.build();
response.addHeader(HttpHeaders.SET_COOKIE, responseCookie.toString());
Disclamer: The flags and their values are provided just as an example for the class' API.
I am not a JEE expert, but I think that because that cookie property is a somewhat new invention, you cannot expect it to be present in Java EE 7 interfaces or implementations. The Cookie
class is missing a setter for generic properties, as it seems. But instead of adding the cookie to your HttpServletResponse
via
response.addCookie(myCookie)
you can simply set the corresponding HTTP header field via
response.setHeader("Set-Cookie", "key=value; HttpOnly; SameSite=strict")
Update: Thanks to @mwyrzyk for pointing out that setHeader()
overwrites all existing headers of the same name. So if you happen have other Set-Cookie
headers in your response already, of course you would use addHeader()
with the same parameters instead.