Today’s protocols and identity practices for web applications are layered on top of HTTP and browser behaviors, which have remained largely unchanged for a long time.
As the use of the web evolves, the proliferation of attacks and the emergence of problematic practices (such as aggressive user tracking from ad platforms) is leading browser makers to introduce new measures to contain those issues. Unfortunately, some identity scenarios are getting caught in the crossfire: as browsers change the “laws of physics” on which protocols and practices rely, existing services and software components will need to adapt or lose their user’s ability to sign in and operate the applications relying on them.
In this article we will discuss one of the most impactful changes on the horizon, the way in which Chrome (and soon after, others) handles cookies in case the SameSite attribute is not set.
SameSite changes impact in a nutshell
Today’s identity flows rely on cookies for two main purposes:
- Keeping track of some information across redirects, and tie it to a particular user agent instance (for example, the Nonce value in OpenID Connect).
- Representing the existence of an authenticated session, typically by emitting a cookie in the domain of the authentication authority (authorization server, IdP depending on the protocol).
Those cookies are often used in cross site protocol legs, where requests go from the authority domain to the app’s, and vice versa.The correct outcome of those protocol exchanges depends on the presence of those cookies in the request.
The SameSite cookie attribute instructs the browser on the circumstances in which a cookie should or should not be sent alongside a request when the domain on which the request originated differs from the destination. SameSite is a relatively new attribute, hence many middlewares and identity providers are not aware of the attribute and therefore don’t set it.
The problem this creates is that starting February 2020, Chrome will change the behavior for cookies that do not explicitly set the SameSite attribute. The new default behavior will be to NOT send cookies with all requests (i.e. the behavior of SameSite=Lax) causing some existing identity flows to malfunction.Firefox will be right behind.
The good news is that the Identirati have been on top of the problem for some time, and nearly every Identity Service Provider in the industry has a plan for guaranteeing business continuity. The bad news is that, if you own a web application leveraging one of the affected flows, you might need to update the identity SDKs to a version that knows how to handle the SameSite attribute.
In the following sections we’ll dig just deep enough to get affected scenarios and remediations in better focus. If you want more details, there’s a growing number of deep dives posts on the internet: we’ll list some relevant links at the end of this article.
SameSite Mechanics and New Default Browser Behavior
Let’s invest a few moments to learn more about SameSite goals and behavior in more detail.
We are all sadly familiar with the cross site request forgery (CSRF) class of attacks. The idea is that a malicious actor can somehow trick the user’s browser to hit a web app where they are authenticated (e.g. they have a session cookie for) and make it perform actions they don’t want, or aren’t aware of.
CSRF attacks are only possible because the malicious requests include session cookies, the artifacts proving that the user has a valid authenticated session. The idea behind SameSite is that by preventing the browser from sending cookies to a domain when a request is triggered from a different domain, the typical way in which CSRF attacks are conducted, the entire class of attacks is mitigated.
The SameSite attribute provides cookie writers various options to dictate in what circumstances browsers should send or withhold cookies to a domain.
- SameSite=Strict determines that a browser will send a cookie for sampledomain.com only if it is already on a sampledomain.com page, or in other words if the request was triggered while the browser was already pointing at the target domain.
- SameSite=Lax will send cookies to sampledomain.com even if the request originated from anotherdomain.com, but only if the request was initiated by a user explicitly clicking a link to sampledomain.com.
- SameSite=None signals to the browser that it’s OK to send cookies to sampledomain.com regardless of how the request originated.
When faced with cookies without any SameSite value set, as of today browsers default to the behavior described so far for None. But as anticipated earlier, around February 2020 Chrome is scheduled to make changes. The new behavior is described in detail here – but in short:
- Cookies without a specified SameSite value will be treated as Lax
- Cookies with SameSite=None must also be marked as Secure (only travel over HTTPS) or will be blocked
Google announced the intent to turn the new behavior on as default in 78 (beta) and Chrome 80 (stable), estimated to be released in February 2020. Firefox already added the behavior as opt in from version 69.
To complicate things: browsers in use today have different ways of reacting to cookies carrying the SameSite attribute, and are unlikely to be all updated to comply with the new behaviors. For example: browsers complying with the earliest SameSite definition will ignore (not send) cookies with any SameSite attribute value other than Lax or Strict, affecting cookies marked with SameSite=None; and WebKit based browsers on iOS version 12 and lower will erroneously interpret SameSite=None as SameSite=Strict. You can find a detailed list of those behaviors in <link>.
This will complicate any remediation strategy we’ll have to apply to preserve identity functionality, forcing identity providers and SDKs to accommodate the different behaviors of multiple browsers- or purposefully forsaking support of some version.
Now that we have a better idea of how SameSite works and what changes are coming our way, we are better equipped to understand what exactly is likely to break in existing identity flows and what remediations are being considered across the identity industry.
Impact on Identity Flows and Remediations
Let’s go back to the two identity flows relying on cookies that were mentioning at the beginning of the article.
To expand on scenario 1, consider the particular instance of a web app implementing web sign on using OpenID Connect and the form_post response type. As part of crafting an authentication request in that style, the web site generated a nonce– a unique value that will be passed to the authorization server and that it is expected to be included, unchanged, in the resulting id_token proving that successful authentication occurred. The idea is that the web app will only accept id_tokens containing a nonce value it recognizes, thus preventing replay attacks.
Here’s the relevant detail: web apps usually save the nonce value in a cookie, so that they can 1) tie to the session with a particular user agent and 2) remain stateless. Normally the cookie containing the nonce is sent to the web app together with the http POST containing the id_token, allowing the web app to perform the necessary comparisons. Today’s nonce cookies are mostly produced without any SameSite value: which means that with the changes described in Chrome 80, those cookies will be considered as SameSite=Lax, and given that the POST originates from the authorization server domain to the app domain, the browser won’t send the nonce cookie… causing the nonce comparison to fail, and the sign in operation to fail altogether.
What’s the solution here? The obvious approach is to modify the logic generating the nonce cookie, typically residing in a middleware or similar component, to carry SameSite=None. That will restore the ability of the browser to include that cookie in POSTs at sign in time.
One extra requirement here is that the nonce cookie must also be marked as Secure and sent over HTTPS, per the new Chrome rules for SameSite=None cookies. That might seem obvious to anyone familiar with how OpenID Connect and OAuth2 work, given that the use of bearer token makes it necessary to perform all communications over secure channels. However, many Identirati are often surprised when learning that applications are routinely hosted on HTTP during the development phase, and many developers aren’t all that familiar with setting up HTTPS. Although as providers we can develop new middlewares and SDKs that set SameSite=None for the nonce cookie, we cannot handle the HTTPS requirements on the developer’s behalf; that is likely to lead at least some developers to abandon standard based flows to less secure solutions, which is why it would be ideal to have browser vendors provide some constraint relaxation in development mode (say admitting SameSite=None on HTTP if the target host is localhost).
The older browsers and the WebKit versions afflicted by the bugs described earlier are also a problem, as their reaction to SameSite=None will be to omit the cookie in the request. Some providers are implementing complex user-agent detecting logic, aimed at determining whether the resulting cookie should include SameSite=None (newer browsers) or not (older browser). The current consensus from the identity community is to circumvent the problem by always emitting two cookies, one with SameSite=None and the other without, at least while the offending browsers aren’t fixed or are no longer supported. The approach isn’t issue-free (platforms generating large cookies are likely to exceed browser limits if they emit duplicates) but it is the best option to date, and the one officially recommended by Google.
The remediation discussed here is largely aimed at web apps and the SDKs/middlewares used to implement web sign on, and in particular the ones using form_post response type (the ones leveraging full page redirects and the authorization code flow for the same purpose aren’t affected).
Let’s also look at scenario 2 in which case an Identity Provider writes a cookie representing the user’s authenticated session and the application uses that cookie via an iframe to refresh the applications tokens. A key aspect of the SameSite processing rules is that cookies marked as SameSite=Lax are NOT sent when requests occur in iframes unless the domain main page and the iframe are the same which is NOT the case for the identity flow referenced above. This affects any Single Page App (amongst other scenarios) that may be using a hidden iframe with OpenID Connect prompt=none processing to refresh tokens within the app. At the time of this article, the only remediation is for the IDP to set the SameSite=None attribute on its authentication session cookies. This is less than ideal as it creates a security exposure for the IDP by allowing those cookies to be sent in 3rd party contexts, increasing the likelihood of CSRF attacks.
This is not the end of changes coming from browser vendors as can be seen by the Intelligent Tracking Protections initiated by Apple as implemented in Safari and other browsers. While ITP is focused and removing the ability of 3rd party advertisers from tracking users across the web, it can have unintended consequences for some Identity flows as well. Discussing these changes in detail is outside the scope of this article though we highly recommend reading through the additional information provided via the included links. Additionally, there are recommendations from the browser vendors to change the way browsers manage state via HTTP State Tokens and also thinking around how browsers can better manage a user’s signed-in state. These topics are also outside the scope of this article but additional links are provided.
If you’ve made it this far, thank you for reading through to the end! The final and primary recommendation is to review any identity related flows in your system to determine if they will be affected by the SameSite changes and make sure to take action before the February 2020 deadline.
Recent Presentations and Blog Posts
Intelligent Tracking Protection
Browser Vendor Proposals
Principal Architect at Auth0
Identity Architect at Verizon Media