Search code examples
google-chromewebcookiessamesite

What are the rules for SameSite=Lax cookies and GET request inside iframe?


The user is on site-a.com and there is an iframe with site-b.com. site-b.com makes GET request back to site-a.com (inside iframe). Will Lax cookies for cross-site GET to site-a.com be send with the request?

To be more clear:

  • Before GET request: site-b.com iframed in site-a.com
  • After GET request: site-a.com iframed in site-a.com

From my observation in Chrome 91 canary this cookie is blocked, while it is not blocked in Chrome 88. I thought that only Lax+POST is problematic but it looks like also Lax+GET is now blocked in some cases. Is there any information/spec. about cross-site GET+Lax cookies?


Solution

  • First off, the request from site-b.com to site-a.com is a cross-site request. Doesn't matter if it's a GET or POST, the fact that it's between two different registrable domains (a.k.a. eTLD+1s) means it's cross-site.

    The specification allows for Lax cookies to be sent with cross-site requests only if they are top-level requests AND have a safe method (GET, but not POST):

       *  If the cookie's same-site-flag is not "None", and the HTTP
          request is cross-site (as defined in Section 5.2) then exclude
          the cookie unless all of the following statements hold:
    
          1.  The same-site-flag is "Lax" or "Default".
    
          2.  The HTTP request's method is "safe".
    
          3.  The HTTP request's target browsing context is a top-level
              browsing context.
    

    A request inside an iframe is not a top-level request, hence Lax cookies aren't sent with a cross-site request on an iframe, regardless of what the request method is.

    Chrome used to have a bug in this behavior, where the top-level requirement wasn't followed exactly. (It used to be that Chrome would send Lax cookies if the iframe and all of its ancestors matched the top level. This was buggy because the spec says it literally needs to be the top level.) What you're seeing is the correct behavior after the bug was fixed in Chrome 90.