SameSite Lax+Post Mitigation Not Working as Expected Enabling CSRF-Attacks
Categories
(Core :: Networking: Cookies, defect, P2)
Tracking
()
People
(Reporter: info, Unassigned)
References
(Blocks 1 open bug)
Details
(Keywords: reporter-external, Whiteboard: [reporter-external] [client-bounty-form] [verif?][necko-triaged][necko-priority-queue])
So there is this scenario where cookies without the SameSite attribute set have a 2-minute grace time window to send them in cross-domain POST requests. However, I noticed while this behavior is correctly implemented in Chrome and Safari, it looks like the latest Firefox does not respect this scenario and still sends any cookie without the SameSite flag cross-domain even after the 2-minute time window has passed.
To reproduce this issue I've created a small scenario that should demonstrate this:
- Go to https://y0.lu/cookie.php which will set a random cookie that has no SameSite flag set. The page will print out the time when the cookie was created.
- Wait for 2 minutes and then go to http://rce.wf/cookie.html and hit the button on the page. This will send a cross-domain POST request (similar to what would be used in a CSRF attack) to https://y0.lu/ with some random data in the POST body and the cookie issued in step #1.
You can also use these steps in Chrome and Safari where you'll notice that they have properly implemented the 2-minute time window, after which the cookies aren't sent cross-domain anymore.
Tested on:
- Firefox 125.0.1 on Macos with default config
- Firefox 125.0.1 on Windows with default config
The scenario works correctly on Chromium 123.0.6312.122 and Safari 17.4.1 (19618.1.15.11.14)
Best,
Julien
Reporter | ||
Comment 1•5 months ago
|
||
Comment 2•5 months ago
|
||
Starting with sec-moderate until we can look into the details and figure out just how broken this is. Not really a vulnerability IN Firefox, but if it's a broken mitigation that could lead to Firefox users being less safe on web applications. --> Cookies
Updated•5 months ago
|
Comment 3•4 months ago
|
||
I'm not sure we implement anything related to "Lax-Allowing-Unsafe" at the moment.
Reporter | ||
Comment 4•4 months ago
|
||
Well, at least there is a config setting called network.cookie.sameSite.laxPlusPOST.timeout
, which initially made me think that Firefox supports this.
Updated•4 months ago
|
Comment 5•4 months ago
|
||
Ah, thanks for pointing that out. It appears we do have this implemented. But since the check depends on aLaxByDefault, and that's currently disabled, we don't actually use it.cd
// 2 minutes of tolerance for 'SameSite=Lax by default' for cookies set
// without a SameSite value when used for unsafe http methods.
if (aLaxByDefault && aCookie->IsDefaultSameSite() &&
StaticPrefs::network_cookie_sameSite_laxPlusPOST_timeout() > 0 &&
currentTimeInUsec - aCookie->CreationTime() <=
(StaticPrefs::network_cookie_sameSite_laxPlusPOST_timeout() *
PR_USEC_PER_SEC) &&
!NS_IsSafeMethodNav(aChannel)) {
Btw, I've just tested with Safari 17.4.1 (same version as comment 0) and the cookie is still sent in the request.
Comment 6•4 months ago
•
|
||
From what I can tell this is just an issue of LaxByDefault expectation. Firefox does not have LaxByDefault currently enabled so the cookie set in the STR will be SameSite=None. So in the case that we perform the cross-site navigation in step 2, we send the cookie, according to spec. That's with or without the timer.
FWIW and just in case the issue is actually still occuring with when laxByDefault is enabled, I also attempted to reproduce with our pref on.
With the same STR, I observed that the cookie was NOT attached to the request on the POST. Though, I did notice it on the GET for favicon, which is also within spec.
Some citation:
When sending a request the spec says a cookie should be excluded in the circumstance where Samesite != None and it is a cross-site request under unless certain conditions are all met. To be explicit those conditions are:
- The retrieval's type is "HTTP".
- The same-site-flag is "Lax" or "Default".
- The HTTP request associated with the retrieval uses a "safe" method. (Where GET is considered a "Safe" method, but POST is not.)
- The target browsing context of the HTTP request associated with the retrieval is the active browsing context or a top-level traversable.
So I think we can actually close this issue as it should resolve if and when we switch to laxByDefault.
I will give this a week or so before closing in case there is a key fact that I missed.
Updated•4 months ago
|
Reporter | ||
Comment 8•3 months ago
|
||
Is there already an ETA when "laxByDefault" will be enabled?
Comment 9•3 months ago
|
||
There are currently no plans to try to enable this feature. In the past, we introduced significant breakage by turning this on and we need to re-visit.
Updated•3 months ago
|
Updated•3 months ago
|
Updated•3 months ago
|
Description
•