The 2 minutes where SameSite=Lax doesn't stop CSRF
Chrome still sends a cookie with no explicit SameSite attribute on a cross-site POST request for the first 120 seconds after it's set. That's a deliberate carve-out from Chrome's own Lax default, built in to avoid breaking SSO flows. How that carve-out works, how the window stays open longer than "just after login," and how to actually defend against it.
SameSite=Lax in one sentence
Since Chrome 80 (February 2020), every cookie without an explicit SameSite attribute automatically gets SameSite=Lax. The idea: a cookie is only sent on requests from your own site, plus on "safe" top-level navigation from another site, such as a user clicking a link. On cross-site POST requests the cookie is not sent: that's precisely the classic CSRF vector, since an auto-submitting form on an attacker's site is cross-site by definition. That, in theory, eliminates most CSRF without a developer having to do anything.
That's the theory. In practice, Chrome built in an exception that makes this story considerably more nuanced.
The exception nobody reads: Lax+POST
From the official Chromium documentation: a cookie that is at most 2 minutes old is still sent on a top-level cross-site POST request, even if that cookie has no explicit SameSite attribute. Chromium itself calls this "Lax+POST" or "Lax+Unsafe," and is upfront that it's a deliberate, temporary mitigation, not a bug.
The reason is pragmatic: some Single Sign-On implementations complete a login with a cross-site POST redirect back to the site, right after the session cookie is set. Enforce strict Lax rules there and you break that login flow. Chrome opted for a 120-second grace period instead of breaking those flows outright.
A nuance that's often overlooked, and the most important one in this entire article: this exception applies only to cookies that don't specify a SameSite attribute. Explicitly write SameSite=Lax in the Set-Cookie header, and you get the "normal" Lax rules with no 2-minute grace period. We'll come back to that when we get to the fix.
Why this is a backdoor for CSRF
The entire point of SameSite=Lax as a CSRF mitigation is that a cross-site POST doesn't get the cookie. Lax+POST reopens that door for a limited time. The attack recipe is simple:
- The target uses a session cookie with no explicit SameSite attribute (the default, and still very common).
- A state-changing endpoint is reachable via POST with no anti-CSRF token, for example "change email address" or "reset password."
- The victim received that cookie less than 2 minutes ago.
Most people stop at point three: the attacker would have to strike within exactly 2 minutes of a login, which sounds impractical. True, if the attacker has to wait for coincidence. But waiting for coincidence isn't the only option.
The trick that stretches the window: cookie refresh
The 2 minutes aren't counted from the very first time that cookie name was ever set. They're counted from the most recent moment the server sent a Set-Cookie for it. If the server issues a new session cookie every time a user completes a login, even when they were already logged in, an attacker can force that moment and thereby open a fresh 2-minute window right when it suits them.
This isn't a hypothesis: PortSwigger's Web Security Academy has a dedicated lab for it, "SameSite Lax bypass via cookie refresh." The scenario: a site with OAuth login that sets a new session cookie on every completion of the OAuth flow, even if the user already had a valid session. The attacker sends the victim's browser through an invisible top-level navigation, say an auto-redirecting popup or window.open, past /social-login. That silently completes the OAuth flow, the server sets a fresh cookie, and the 2-minute clock restarts for a session that already existed. A few seconds later, a hidden form submits the actual CSRF payload, changing the email address, say, and the fresh cookie goes right along with it.
The upshot: the window isn't "the first 2 minutes after login." It's "the first 2 minutes after any opportunity the attacker can find to force a repeated cookie issuance." On sites that refresh the session cookie on every re-authentication, or even on every request through rolling or sliding sessions, that window can stay open almost continuously for an actively logged-in user.
None of this is an unknown vulnerability in Chrome. It's named and explained in the official Chromium documentation, and PortSwigger has taught the cookie-refresh technique in the Web Security Academy for years. The problem isn't that this is hidden. It's that many developers conflate SameSite=Lax (implicit, via the browser default) with "cross-site POST is always blocked."
How to close this in your own application
Always set SameSite explicitly
The simplest, most concrete fix: write SameSite=Lax (or Strict, where possible) yourself in the Set-Cookie header, rather than relying on the browser default. As described above, the Lax+POST grace period applies only to cookies without an explicit attribute. One word's difference in your response header, and the entire attack scenario in this article no longer applies.
Set-Cookie: session=abc123; Path=/; HttpOnly; Secure
(implicit Lax, exposed to the 2-minute window)
Set-Cookie: session=abc123; Path=/; HttpOnly; Secure; SameSite=Lax
(explicit, no Lax+POST exception)
Don't rely on SameSite as your only CSRF defence
SameSite is a strong, free layer of defence, but it's still just a layer: not a replacement for anti-CSRF tokens on state-changing endpoints. For sensitive actions such as changing email, resetting passwords, payments, or account settings, an unpredictable token or a double-submit cookie pattern remains the actual guarantee. SameSite catches what slips through, but it doesn't replace the check itself.
Audit endpoints that quietly refresh a session cookie
Walk through every endpoint that sends a Set-Cookie for your session without the user consciously logging in again: SSO callbacks, "remember me" refresh, rolling-session middleware that re-sets the cookie on every request. Is any of those reachable via a simple top-level navigation, such as a link, a redirect, or a window.open, without the user having to do anything? That's exactly the gadget the cookie-refresh technique needs.
For SSO/OAuth flows: choose explicitly, don't rely on grace periods
Does your own login flow need a cross-site POST redirect to survive with the session intact? Use SameSite=None; Secure deliberately for that specific cookie, rather than leaning on a grace-period rule that Chrome itself has labelled "temporary" for years and could remove at any point.
Conclusion
SameSite=Lax is a good default that removes a large share of CSRF without anyone having to do anything. But "a large share" isn't "all of it," and certainly not "from second one." The Lax+POST mitigation is a deliberate, documented exception, and the cookie-refresh technique shows that the window it opens is often wider than "the first 2 minutes after login."
The fix costs one line in most stacks: write SameSite explicitly instead of letting the browser default apply, and treat it as a complement to anti-CSRF tokens, not a replacement.
Is your application quietly relying on browser defaults?
SameSite, CORS, cookie flags: exactly the kind of configuration a manual pentest checks and an automated scan skips.
Go to web application pentest →