Closed Bug 1965430 (CVE-2026-8950) Opened 1 year ago Closed 5 months ago

Form POST requests do not set Origin header to null after redirect

Categories

(Core :: Networking: HTTP, defect, P2)

Firefox 138
defect

Tracking

()

RESOLVED FIXED
151 Branch
Tracking Status
firefox-esr115 --- wontfix
firefox-esr140 151+ fixed
firefox147 --- wontfix
firefox148 --- wontfix
firefox149 --- wontfix
firefox150 --- wontfix
firefox151 + fixed

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)

1.41 KB, application/zip
Details
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
Attached file exploit.zip —

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.

  1. szymsza.cz submits a POST form to szymsza.com
  2. szymsza.com does a 307 redirect to szymsza.eu
  3. 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"

Group: core-security → network-core-security

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.

Severity: -- → S3
Flags: needinfo?(smayya)
Priority: -- → P2
Whiteboard: [necko-triaged] [necko-priority-queue]

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.

Keywords: sec-moderate
See Also: → 1535795, 1605305
Assignee: nobody → smayya
Flags: needinfo?(smayya)
Attached file (secure) —

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.

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?

Flags: needinfo?(tschuster)

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.

Flags: needinfo?(tschuster)

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.

Pushed by agoloman@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/eae8f8fda0fc https://hg.mozilla.org/integration/autoland/rev/9cc3b8e1e2ad Revert "Bug 1965430 - Update ShouldTaintReplacementChannelOrigin. r=tschuster" for causing failures @audioworklet.https.sub.html.

Backed out for causing wpt failures @audioworklet.https.sub.html.

Flags: needinfo?(smayya)

The bug has a release status flag that shows some version of Firefox is affected, thus it will be considered confirmed.

Status: UNCONFIRMED → NEW
Ever confirmed: true

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.

Flags: needinfo?(ghess)

(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 Origin header. 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).

Flags: needinfo?(smayya)
Pushed by rperta@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/2bb8897a439e https://hg.mozilla.org/integration/autoland/rev/8339afaf0a6b Revert "Bug 1965430 - Update ShouldTaintReplacementChannelOrigin. r=tschuster" for causing failures at test_origin_header_redirect.html

TEST-UNEXPECTED-TIMEOUT | netwerk/test/mochitests/test_origin_header_redirect.html | application timed out after 370.0 seconds with no output

Flags: needinfo?(smayya)
Pushed by smolnar@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/98f4baff42a4 https://hg.mozilla.org/integration/autoland/rev/9a64aadd3871 Revert "Bug 1965430 - Update ShouldTaintReplacementChannelOrigin. r=tschuster" for causing mochitest crashes @ test_origin_header_redirect.html
[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

Looks like the linter was changing the url to use https instead of http - http://test1.mochi.test:8888. Added eslint disable

Flags: needinfo?(smayya)
Group: network-core-security → core-security-release
Status: NEW → RESOLVED
Closed: 5 months ago
Resolution: --- → FIXED
Target Milestone: --- → 151 Branch

Please add uplift requests for esr140

Flags: needinfo?(smayya)
Flags: needinfo?(smayya)
Attached file (secure) —
Attachment #9571925 - Flags: approval-mozilla-esr140?

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

Uplifted request submitted https://lando.moz.tools/uplift/jobs/2039/

Attachment #9571925 - Flags: approval-mozilla-esr140? → approval-mozilla-esr140+
QA Whiteboard: [sec] [qa-triage-done-c152/b151]
Whiteboard: [necko-triaged] [necko-priority-queue] → [necko-triaged] [necko-priority-queue][adv-main151+][adv-esr140.11+]
Alias: CVE-2026-8950
Group: core-security-release
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: