Setting the SameSite attribute on cookies with Open Liberty
On Open Liberty, you can now specify the SameSite
cookie attribute for your application-defined cookies, as well as for the session and security cookies, and any cookie added to the response by the server, in your server configuration and minimize application-level changes. The SameSite
cookie attribute is used by web browsers to determine if a particular cookie should be sent with a request.
Until recently, if the attribute wasn’t set, Google Chrome assumed the value of the attribute to be None
and allowed third-party cookies to track users across multiple sites. A recent change to Chrome (and other web browsers will follow), however, has changed this default behavior so that cookies are only sent for "same-site" and "cross-site" top-level navigations specified in the cookie (Lax
). To change this behaviour, the SameSite
attribute must be explicitly set.
The Servlet specification does not offer any API to set the SameSite
attribute on a Cookie so there historically was only one way to set the SameSite
attribute on cookies in Open Liberty and that was to manually write the Set-Cookie
header and add it to the HttpServletResponse. The update in Open Liberty 20.0.0.3 means that you can specify the SameSite
cookie attribute for your application-defined cookies. These new server configurations help minimize application-level changes due to the new handling of the SameSite
attribute.
What is the SameSite cookie attribute?
The SameSite
attribute is used by web browsers to determine if a particular cookie should be sent with a request. Setting this attribute can help protect against Cross Site Request Forgery (CSRF) attacks. There are three values for the SameSite
attribute: Lax
, Strict
, None
:
SameSite=Strict
-
The cookie is only sent with "same-site" requests. The cookie is only sent by the web browser if the site for the cookie matches the site in the address bar for example.
SameSite=Lax
-
The cookie is sent with both "same-site" and "cross-site" top-level navigation requests. Clicking a link, for example.
SameSite=None
-
The cookie is sent with both "same-site" and "cross-site" requests. The cookie is sent by the web browser for third-party contexts, embedded content, for example.
What’s changing with the SameSite cookie attribute?
Google Chrome and other web browsers are starting to change how they deal with cookies that do not have a SameSite
attribute defined. There are two main changes:
-
Cookies without a
SameSite
attribute are treated as if they have theSameSite
attribute value ofLax
(instead ofNone
, which was the previous browser behavior). -
Cookies defined as having a
SameSite
attribute value ofNone
now also require that you define theSecure
attribute.
The SameSite
attribute is not a new concept and is detailed in great length here: HTTP State Management Mechanism. Until recently web browsers have treated a Cookie without a SameSite
attribute as having a SameSite
attribute value of None
. Details of the new enforcement that has been adopted by Chrome and by other browser in future can be found here: Incrementally Better Cookies
Setting the SameSite attribute
Open Liberty is providing three new ways of setting the SameSite
attribute because it is not possible to set the SameSite
attribute using the Cookie API.
Previously, the only available way to set the SameSite
attribute using the Servlet specification is specifically defining a Set-Cookie
header using the following two HttpServletResponse APIs:
Now, there are three new ways to set the SameSite
attribute in Open LIberty in the server.xml
configuration:
-
For the session cookie
-
For the LTPA/JWT security cookies
-
For other cookies
(This work was completed in the Allow the SameSite attribute to be set on a Cookie issue.)
Setting the SameSite attribute for the session cookie
In the server.xml
:
<httpSession cookieSameSite="Lax|Strict|None|Disabled"/>
The default value of cookieSameSite
is Disabled
. The Disabled
value means that no SameSite
attribute is added to the session cookie.
If the None
value is used for cookieSameSite
, the Secure
attribute is automatically added to the session cookie.
Setting the SameSite attribute for the LTPA/JWT security cookies
In the server.xml
:
<webAppSecurity sameSiteCookie="Lax|Strict|None|Disabled"/>
The default value of sameSiteCookie
is Disabled
. The Disabled
value means that no SameSite
attribute is added to the security cookies.
If the None
value is used for sameSiteCookie
, the Secure
attribute is automatically added to the security cookies.
Setting the SameSite attribute for other cookies
In the server.xml
:
<httpEndpoint id="defaultHttpEndpoint"
httpPort="9080"
httpsPort="9443" >
<samesite lax="chocolateChip,oatmeal" strict="peanutButter" none="sugar"/>
</httpEndpoint>
Each attribute of the samesite
element takes a comma (,
) deliminted list of cookie names.
In the example, cookies with the following names would have the SameSite
attribute defined as follows:
- chocolateChip
and oatmeal
have a SameSite
attribute of Lax
- peanutButter
have a SameSite
attribute of Strict
- sugar
have a SameSite
attribute of None
and the Secure
attribute is automatically added
The httpEndpoint
configuration adds the SameSite
attribute to a cookie only if it does not already exist.
The httpEndpoint
configuration gives the ability to add the SameSite
attribute to cookies added with the HttpServletResponse.setHeader and HttpServletResponse.addHeader methods, as well as any cookies added using HttpServletResponse.addCookie(Cookie cookie).
The httpEndpoint
configuration also supports the wildcard character (*
).
In the following example, all cookies added by the application and the server have the SameSite attribute set to Lax
:
<samesite lax="*"/>
In the following example, sugar
has the SameSite attribute set to None
and the Secure attribute added, peanutButter
has the SameSite attribute set to Strict
, and all other cookies have the SameSite attribute set to Lax
:
<samesite lax="*" strict="peanutButter" none="suga*"/>
If the httpSession
and/or webAppSecurity
configurations are not set, given the above examples, the session cookie’s SameSite
attribute value is Lax
and the security cookie’s SameSite
attribute value is Lax
.
Any number of cookie names can contain the wildcard character at the end and, for any given cookie name, the most specific pattern is matched. Only one standalone wildcard character is allowed and the following example shows an invalid configuration because each cookie name or pattern can be defined only as one of none
, lax
, or strict
:
<samesite lax="*" strict="*"/>
If you have a SameSite configuration to use in multiple endpoints, you can create the configuration in one locaton and refer to it from the server configuration of each endpoint. For example:
<httpEndpoint id="defaultHttpEndpoint"
httpPort="9080"
httpsPort="9443"
samesiteRef="samesiteReference">
</httpEndpoint>
<samesite strict="cookieOne" id="samesiteReference"/>
Finally, the configuration for httpSession
and webAppSecurity
take precedence over the httpEndpoint
configuration, if set. In the following example, the session cookie with the name JSESSIONID
(the default session cookie name) has the SameSite
attribute set to Lax
:
<httpSession cookieSameSite="Lax"/>
<httpEndpoint id="defaultHttpEndpoint"
httpPort="9080"
httpsPort="9443" >
<samesite strict="JSESSIONID"/>
</httpEndpoint>
Summary
Google Chrome and other web browsers are changing how they treat cookies that don’t have a SameSite
attribute defined. As the Servlet specification lacks an API to set the SameSite
attribute on Cookie objects, Open Liberty provides a way of setting the attribute in the server configuration in order to minimize application-level changes.