back to all blogsSee all blog posts

Setting the SameSite attribute on cookies with Open Liberty

image of author
Paul Nicolucci on Mar 25, 2020
Post available in languages:

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.

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.

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 the SameSite attribute value of Lax (instead of None, which was the previous browser behavior).

  • Cookies defined as having a SameSite attribute value of None now also require that you define the Secure 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.)

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.