Difference between revisions of "SameSite"

From MgmtWiki
Jump to: navigation, search
(Context)
(Description of Impact)
 
(3 intermediate revisions by the same user not shown)
Line 4: Line 4:
 
==Context==
 
==Context==
 
* Cross-site scripting (XSS) attacks have allows an attacker to see and reuse cookies supplied for [[Authentication]] of a user by another site.
 
* Cross-site scripting (XSS) attacks have allows an attacker to see and reuse cookies supplied for [[Authentication]] of a user by another site.
* New HTTP headers focus on [[Cross-Origin iFrame]]s which complicates the terms sites and origins which is future explained on that wiki page.
+
* New HTTP headers focus on [[Cross-Origin iFrame]]s which complicates the terms sites and origins which is further explained on that wiki page.
 +
===Description of Impact===
 +
This is largely from Brock Allen (see below) and D Waite at Ping.
 +
 
 +
There is another leg to this workflow, though, which is affected by the scenario you describe Brian. And it's what breaks the login workflow (cross-site). My observations are from trying to reverse engineer what the browser is doing, so I don't know if it's intended. Also, it's complicated and I've always had a hard time explaining what I think is happening, so apologies in advance.
 +
 
 +
During this workflow, if the RP then issues its own SameSite=Strict (and Lax too IIRC) session cookie on that exact POST response and also emits a 302 elsewhere in the RP, then on that next request the browser makes it will omit sending the cookie. I think it does this because it detects that you're in the middle of a long redirect chain which originated at the OP and has crossed the line into the RP (cross-site). The end result is that it won't send the RP session cookie on that final request, and from the end user's (and RP's) perspective this last request is anonymous. I know this is complicated to follow, so apologies.
 +
 
 +
Interestingly, though, if the user were to just hit refresh in the browser or manually navigate to somewhere in the RP, then the cookie is sent normally since it's the user that initiates the request. IOW, on the POST cross-site, the browser accepts the cookie just fine. It's just that it doesn't send it on the request because the request chain looks initiated from cross-site.
 +
 
 +
SameSite applies in navigation capacities as well, e.g. the first HTTP request to the new site on link, redirect, or post. None and the temporary chromium default workaround behavior would be the only ones that would send state along with a HTTP POST. A world with just lax and strict would require more complex server acrobatics.
 +
 
 +
I’m (also) not Sam, but I can try to supply a bit of color:
 +
 
 +
SameSite is meant to limit state outside first-party contexts, e.g. limit XSRF-style attacks by having the browser not send state for request originating from outside your domain. It was NOT intended as a privacy restriction.
 +
 
 +
SameSite is a per-cookie setting when interacting outside your current context. Examples would be cookies not being sent when following links, when being redirected, on cross-domain POSTs (manual or javascript) - in addition to embedded resources (images, iframes) and XHR/fetch.
 +
 
 +
The current behaviors of SameSite are:
 +
{|border="1" padding="2" width="799px"
 +
| Setting || Behavior
 +
|-
 +
| None || always send cookies
 +
|-
 +
|Lax ||  Send on ’Safe’ requests (GET, HEAD, OPTIONS)
 +
|-
 +
| “Chromium”  || Lax but send also on POST when cookie < 2 minutes old
 +
|-
 +
|Strict||  Never Send
 +
|}
 +
 
 +
Chromium-based applications will typically default to the implicit “Chromium” behavior if SameSite is not set and the cookie is set to Secure, otherwise Strict.  This temporary default behavior is specifically to avoid immediately breaking SSO software, but will still break if you need state older than two minutes - including if your login process winds up taking a bit longer due to a slow emailed OTP or mandatory password change.
 +
 
 +
Other browsers have other defaults - they may default to None, or default to None only for Secure cookies. Chrome also unfortunately mandated SameSite=None for legacy behavior before it was part of any officially proposed standard - other browser makers did support it, but there are some not-super-old environments which have to be detected so you don’t send an illegal SameSite value of None (and thus have your attempt to set a cookie be rejected).
 +
 
 +
My understanding is that even with Strict-mode causing cookies to be omitted on a cross-domain form post, the _next_ server response within the context of the domain will have these cookies sent. Catching the form and doing a redirect for processing would be one way to get state back.
 +
 
 +
SameSite settings are meant to control cross-site usability of your domain, and are more in the family of CORS restrictions than privacy restrictions. However, it does make several tracker integration strategies more complex (e.g. javascript processing of inbound decorated links, XHR calls, iframe embedding)
 +
 
 +
Restricting SameSite as a privacy setting brings up piles of edge cases that I just don’t know about. E.g.:
 +
* on first page load on a new site, would the javascript have cookie access?
 +
* would there be corresponding limitations for javascript access to local storage?
 +
* are cookies still settable, and does _that_ depend on same site at all?
 +
* wouldn’t leaving ‘lax’ as an option be a large loophole for data on GETs?
 +
 
 +
As such, I suspect removing SameSite=None is really being talked about as a potential part of a suite of changes. Unfortunately, I have not found a reference to that for Chromium, let alone a reference that makes me think all browsers are collaborating on a gameplan in the open. If others know of one, please share!
  
 
==Problems==
 
==Problems==

Latest revision as of 11:52, 8 May 2021

Full Title or Meme

SameSite is an attribute in HTTP that is applied to the Cookie header.

Context

  • Cross-site scripting (XSS) attacks have allows an attacker to see and reuse cookies supplied for Authentication of a user by another site.
  • New HTTP headers focus on Cross-Origin iFrames which complicates the terms sites and origins which is further explained on that wiki page.

Description of Impact

This is largely from Brock Allen (see below) and D Waite at Ping.

There is another leg to this workflow, though, which is affected by the scenario you describe Brian. And it's what breaks the login workflow (cross-site). My observations are from trying to reverse engineer what the browser is doing, so I don't know if it's intended. Also, it's complicated and I've always had a hard time explaining what I think is happening, so apologies in advance.

During this workflow, if the RP then issues its own SameSite=Strict (and Lax too IIRC) session cookie on that exact POST response and also emits a 302 elsewhere in the RP, then on that next request the browser makes it will omit sending the cookie. I think it does this because it detects that you're in the middle of a long redirect chain which originated at the OP and has crossed the line into the RP (cross-site). The end result is that it won't send the RP session cookie on that final request, and from the end user's (and RP's) perspective this last request is anonymous. I know this is complicated to follow, so apologies.

Interestingly, though, if the user were to just hit refresh in the browser or manually navigate to somewhere in the RP, then the cookie is sent normally since it's the user that initiates the request. IOW, on the POST cross-site, the browser accepts the cookie just fine. It's just that it doesn't send it on the request because the request chain looks initiated from cross-site.

SameSite applies in navigation capacities as well, e.g. the first HTTP request to the new site on link, redirect, or post. None and the temporary chromium default workaround behavior would be the only ones that would send state along with a HTTP POST. A world with just lax and strict would require more complex server acrobatics.

I’m (also) not Sam, but I can try to supply a bit of color:

SameSite is meant to limit state outside first-party contexts, e.g. limit XSRF-style attacks by having the browser not send state for request originating from outside your domain. It was NOT intended as a privacy restriction.

SameSite is a per-cookie setting when interacting outside your current context. Examples would be cookies not being sent when following links, when being redirected, on cross-domain POSTs (manual or javascript) - in addition to embedded resources (images, iframes) and XHR/fetch.

The current behaviors of SameSite are:

Setting Behavior
None always send cookies
Lax Send on ’Safe’ requests (GET, HEAD, OPTIONS)
“Chromium” Lax but send also on POST when cookie < 2 minutes old
Strict Never Send

Chromium-based applications will typically default to the implicit “Chromium” behavior if SameSite is not set and the cookie is set to Secure, otherwise Strict. This temporary default behavior is specifically to avoid immediately breaking SSO software, but will still break if you need state older than two minutes - including if your login process winds up taking a bit longer due to a slow emailed OTP or mandatory password change.

Other browsers have other defaults - they may default to None, or default to None only for Secure cookies. Chrome also unfortunately mandated SameSite=None for legacy behavior before it was part of any officially proposed standard - other browser makers did support it, but there are some not-super-old environments which have to be detected so you don’t send an illegal SameSite value of None (and thus have your attempt to set a cookie be rejected).

My understanding is that even with Strict-mode causing cookies to be omitted on a cross-domain form post, the _next_ server response within the context of the domain will have these cookies sent. Catching the form and doing a redirect for processing would be one way to get state back.

SameSite settings are meant to control cross-site usability of your domain, and are more in the family of CORS restrictions than privacy restrictions. However, it does make several tracker integration strategies more complex (e.g. javascript processing of inbound decorated links, XHR calls, iframe embedding)

Restricting SameSite as a privacy setting brings up piles of edge cases that I just don’t know about. E.g.:

  • on first page load on a new site, would the javascript have cookie access?
  • would there be corresponding limitations for javascript access to local storage?
  • are cookies still settable, and does _that_ depend on same site at all?
  • wouldn’t leaving ‘lax’ as an option be a large loophole for data on GETs?

As such, I suspect removing SameSite=None is really being talked about as a potential part of a suite of changes. Unfortunately, I have not found a reference to that for Chromium, let alone a reference that makes me think all browsers are collaborating on a gameplan in the open. If others know of one, please share!

Problems

  • The use of Cookies on various devices and User Agents has be restricted in ever more severe ways. These restrictions have limited the functionality of the Authentication Cookie.
  • In particular Apple introduced a restriction on SameSite cookies that caused common implementations of OAuth 2.0 and OpenID Connect to fail. Brock Allen has decoded that issue on his site[1] The basic problem with OAuth front channel Authentication is determining which site is the SameSite. So, while the authentication works, the redirect to the client code is not considered, by iOS 12, to be a same-site operation. Even in the case a refresh of the client site will work and be fully authenticated, because it is not a redirect, but a SameSite operation.

References

  1. Brock Allen, Same-site cookies, ASP.NET Core, and external authentication providers. (2019-01-11) https://brockallen.com/2019/01/11/same-site-cookies-asp-net-core-and-external-authentication-providers/

Other Materiel