Form POST requests do not set Origin header to null after redirect
Categories
(Core :: Networking: HTTP, defect, P2)
Tracking
()
People
(Reporter: jakub, Assigned: smayya)
References
Details
(Keywords: csectype-sop, reporter-external, sec-moderate, Whiteboard: [necko-triaged] [necko-priority-queue][adv-main151+][adv-esr140.11+])
Attachments
(3 files)
User Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36
Steps to reproduce:
If a POST form is submitted from origin A to origin B, and the endpoint at origin B uses a 307 redirect to a cross-origin URL C, the Origin header should be set to null. However, URL C receives the Origin header with the value A.
This is similar to the bug https://bugzilla.mozilla.org/show_bug.cgi?id=1649888 with the difference that the bug was about using fetch to request a CORS-enabled server (in which case the Origin header does get correctly erased), whereas the bug I discovered concerns a submitted form.
The security impact is limited, since it only impacts scenarios where A submits a form to malicious B, C validates the Origin header and trusts the A origin, and the simple form request can trigger a CSRF. Nonetheless, the behavior is incorrect, and there could be edge case scenarios where this can lead to an exploit.
To reproduce the issue, go to https://szymsza.cz/exploit/form.html (or see the attached proof of concept) and click on Submit form.
- szymsza.cz submits a POST form to szymsza.com
- szymsza.com does a 307 redirect to szymsza.eu
- szymsza.eu prints out the Origin header it received
Actual results:
Firefox outputs "Received Origin: https://szymsza.cz"
The bug seems to have been present since version 70, when the Origin header was introduced for POST requests, until the latest version
Expected results:
Chromium-based browsers and Safari correctly output "Received Origin: null"
Updated•1 year ago
|
Comment 1•1 year ago
|
||
The problem seems to be around here:
if (IsNewChannelSameOrigin(aNewChannel)) {
return false;
}
IsNewChannelSameOrigin returns false to indicate this is a cross origin redirect. However, we ignore the result and use the result from CheckSameOriginURI(mOriginalURI, mURI, false, false) instead.
Sunil, since you touched this code in bug 1817980, could you take a look?
Thanks.
Updated•1 year ago
|
Comment 2•1 year ago
|
||
This sounds exactly like the original example in bug 1535795 which was supposedly fixed in bug 1605305, but I don't see anyone say they verified the original testcase was fixed. Also there were several regressions from bug 1605305 so it's possible one of those fixes un-fixed the security bug.
| Assignee | ||
Updated•1 year ago
|
| Assignee | ||
Comment 3•9 months ago
|
||
The condition for checking if a new channel is same-origin was inverted.
When the new channel is NOT same-origin to the redirecting channel,
we should taint the origin, not the other way around.
| Assignee | ||
Comment 4•8 months ago
•
|
||
Tom, I see that we have added the test cases covering the described scenario here https://phabricator.services.mozilla.com/D147091#change-26UMaFyrwp9M, we expect the origin to be sent for cross-origin redirects. I think these cases need to be updated to ensure that we send null origin header for cross-origin redirects?
Comment 5•8 months ago
•
|
||
I at first glance, I don't think so. Cross-origin URLs should only really be turned to null with a "same-origin" referrer policy, which this doesn't seem to be.
As far as I can tell Chrome also sends the Origin in this case.
Edit: Not sure what I was looking at, but Chrome sends null.
Comment 6•8 months ago
|
||
Yes, we should be censoring the Origin for cross-origin redirects, even without the "same-origin" referrer policy. So updating the tests is okay.
The reason for this how serializing a request origin works, which is called (indirectly) by append a request Origin header. Thanks Sunil for pointing me in the right direction, I had totally forgotten that part of this censoring happens there.
Comment 9•8 months ago
|
||
Backed out for causing wpt failures @audioworklet.https.sub.html.
Updated•8 months ago
|
Comment 10•8 months ago
|
||
The bug has a release status flag that shows some version of Firefox is affected, thus it will be considered confirmed.
Comment 11•8 months ago
|
||
The bug is marked as tracked for firefox148 (beta) and tracked for firefox149 (nightly). However, the bug still has low severity.
:ghess, could you please increase the severity for this tracked bug? If you disagree with the tracking decision, please talk with the release managers.
For more information, please visit BugBot documentation.
Comment 12•8 months ago
|
||
Received confirmation this won't be fixed for Fx148
Updated•7 months ago
|
| Assignee | ||
Comment 13•5 months ago
|
||
(In reply to Tom Schuster from comment #6)
Yes, we should be censoring the Origin for cross-origin redirects, even without the "same-origin" referrer policy. So updating the tests is okay.
The reason for this how serializing a request origin works, which is called (indirectly) by append a request
Originheader. Thanks Sunil for pointing me in the right direction, I had totally forgotten that part of this censoring happens there.
I checked again. The tests were actually correct in their expectations. The point that we missed what the origin must NOT be tainted if the redirecting page and the page page that initiated the request are same (even if its a cross-origin redirect).
Comment 14•5 months ago
|
||
Comment 15•5 months ago
|
||
Comment 16•5 months ago
|
||
TEST-UNEXPECTED-TIMEOUT | netwerk/test/mochitests/test_origin_header_redirect.html | application timed out after 370.0 seconds with no output
Comment 17•5 months ago
|
||
Comment 18•5 months ago
|
||
Comment 19•5 months ago
|
||
[task 2026-04-14T21:03:37.507+00:00] 21:03:37 INFO - TEST-START | netwerk/test/mochitests/test_origin_header_redirect.html
[task 2026-04-14T21:10:01.590+00:00] 21:10:01 INFO - wait for org.mozilla.geckoview.test_runner complete; top activity=org.mozilla.geckoview.test_runner
[task 2026-04-14T21:10:01.590+00:00] 21:10:01 INFO - org.mozilla.geckoview.test_runner unexpectedly found running. Killing...
[task 2026-04-14T21:10:15.016+00:00] 21:10:15 ERROR - TEST-UNEXPECTED-FAIL | netwerk/test/mochitests/test_origin_header_redirect.html | application timed out after 370 seconds with no output
| Assignee | ||
Comment 20•5 months ago
•
|
||
Looks like the linter was changing the url to use https instead of http - http://test1.mochi.test:8888. Added eslint disable
Comment 21•5 months ago
|
||
Comment 22•5 months ago
|
||
Updated•5 months ago
|
| Assignee | ||
Updated•5 months ago
|
| Assignee | ||
Comment 24•5 months ago
|
||
Original Revision: https://phabricator.services.mozilla.com/D278269
Updated•5 months ago
|
Comment 25•5 months ago
|
||
firefox-esr140 Uplift Approval Request
- User impact if declined/Reason for urgency: This is a security vulnerability, where we might leak the origin info to a third-party site.
- Code covered by automated testing?: yes
- Fix verified in Nightly?: yes
- Needs manual QE testing?: no
- Steps to reproduce for manual QE testing:
- Risk associated with taking this patch: medium
- Explanation of risk level: With this change we will taint origin header for cross-origin redirects for requests. This is the existing behavior for fetch and xhr but was missed for http. There is medium risk to uplift as there might be some edge cases that we might have missed and might encounter them when we deploy this fix.
- String changes made/needed?: No
- Is Android affected?: yes
| Assignee | ||
Comment 26•5 months ago
|
||
Uplifted request submitted https://lando.moz.tools/uplift/jobs/2039/
Updated•5 months ago
|
Updated•5 months ago
|
Comment 27•5 months ago
|
||
| uplift | ||
Updated•5 months ago
|
Updated•4 months ago
|
Updated•4 months ago
|
Updated•4 months ago
|
Updated•1 month ago
|
Description
•