Closed Bug 1790311 (CVE-2022-45411) Opened 2 years ago Closed 2 years ago

Generic CORS bypass that enables Cross-Site-Tracing (XST)

Categories

(Core :: DOM: Networking, defect, P1)

Firefox 104
defect

Tracking

()

RESOLVED FIXED
108 Branch
Tracking Status
firefox-esr102 107+ fixed
firefox106 --- wontfix
firefox107 + fixed
firefox108 + fixed

People

(Reporter: martin.oneal, Assigned: smayya, Mentored)

References

Details

(Keywords: csectype-sop, sec-moderate, sec-vector, Whiteboard: [necko-triaged][post-critsmash-triage][adv-main107+][adv-esr102.5+])

Attachments

(3 files)

Steps to reproduce:

Cross Site Tracing (XST) used to be an effective way to bypass local controls and gain access to authorization headers and cookies protected by httponly attributes. However, for many years the main browsers have implemented limits on fetch and XMLHttpRequest that stop the direct use of the TRACE method.

Out in the real world, some servers that implement CORS simply echo back the contents of the Access-Control-Request-Headers request header in the Access-Control-Allow-Headers response header. This means that it is possible to add an X-Http-Method-Override: TRACE header, which will bypass CORS protections.

The result being that if certain conditions are met (a server has lax CORS, implements the TRACE method and the X-Http-Method-Override header), then fetch and XMLHttpRequest can still be used to bypass CORS and deliver an XST attack.

This will allow any functional XSS on the site to gain access to authorization headers and cookies protected by httponly attributes.

An example of a server with CORS that echos back the Access-Control-Request-Headers header:

fetch( 'https://realtime.www.linkedin.com/realtime/connect', {
method: 'GET',
mode: 'cors',
headers: {
'x-http-method-override': 'TRACE'
}
} );

Actual results:

The combination of issues allows an XST attack to be delivered.

Expected results:

The TRACE method should be blocked in requests from fetch and XMLHttpRequest, whether it is in the main method parameter, or in common override headers ( 'x-http-method-override, x-http-method, x-http-override )

Hi,

It appears this issue affects all the main browsers, and it also appears that the description above may not be the clearest possible.

I'll have another go at explaining, which should hopefully clear things up.

So a normal CORS fails because the TRACE method is blocked. This is something inherrent in all the major browsers, and was a deliberate change to stop XST.

You can see this in action if you browse to https://www.linkedin.com, then paste the following into the browser console. You'll see the browser block the request. All good.

fetch( 'https://realtime.www.linkedin.com/realtime/connect', {
      method: 'TRACE',
      mode: 'cors',
      cache: 'no-store'
} ).then( response => { console.log( response ) } ) 

Now instead, paste in the following. The CORS succeeds and the TRACE overide is sent. Not so good.

fetch( 'https://realtime.www.linkedin.com/realtime/connect', {
      method: 'GET',
      mode: 'cors',
      cache: 'no-store',
      headers: {
            'x-http-method-override': 'TRACE'
      }
} ).then( response => { console.log( response ) } ) 

All that is required are three things to leverage this into a working XST attack (which can be used with any XSS to bypass the httponly flags and also gain access to any authentication tokens in the header):

  • a server that echos the CORS request headers (there are oodles of these);
  • a server with TRACE enabled (there are also lots of these: people don't consider it an issue any more because CORS should protect it); and
  • a server that responds to x-http-method-override: TRACE (less of these, but there are still plenty about).

Hopefully that helps your triage.

Just had confirmation from the Google team that they consider this a security bug in chrome, and are going ahead with a fix.

Well, this is fun. Thank you for the report.

Do you know the origin of this x-http-method-override thing? I found https://www.ibm.com/docs/en/odm/8.10?topic=methods-overriding-security-restrictions-http and https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-odata/bdbabfa6-8c4a-4741-85a9-8d93ffd66c41 but no formal specs or definitions of how this is supposed to interact with CORS.

Given this is a cross-browser issue I expect that we might need a spec update. I also wonder how this interacts with CORS simple / preflighted requests - I guess setting the header makes it a preflight request anyway? But it's ironic that both those documents basically go "ah yes, these pesky security restrictions from firewalls, here is how you bypass them", apparently without anyone thinking that maybe there were reasons for some of the security restrictions...

(In reply to scarlet from comment #2)

Just had confirmation from the Google team that they consider this a security bug in chrome, and are going ahead with a fix.

Thanks for this as well - could you link to the chromium ticket? (Fine if confidential/hidden, but it will help us coordinate and avoid 0-daying the other browsers...)

Valentin: I think this is DOM: networking because fetch/xhr, but feel free to move to "regular" networking if I'm wrong...

Group: firefox-core-security → dom-core-security
Status: UNCONFIRMED → NEW
Component: Untriaged → DOM: Networking
Ever confirmed: true
Flags: needinfo?(valentin.gosu)
Flags: needinfo?(martin.oneal)
Product: Firefox → Core
Flags: needinfo?(martin.oneal)

The override headers have been around fooooorever. Like you point out, they were originally plugged in by app devs to bypass pesky firewall restrictions.

But a lot of sites have these overrides enabled by default (plenty of big names in there ;) and also, so many sites have at least one CORS endpoint that simply reflects back all the headers (origin, allow and auth).

To help with the triage, I've run up a full PoC so that it is clear what the problem is, and how it works.

First browse to https://xst.scarlet.ae so the cookies are set (and you have something sensitive in the headers).

Then browse to any other site (such as https://www.google.com) so that CORS will be activated.

Then paste the following into the browser developer tools, console tab:

fetch( 'https://xst.scarlet.ae/', {
      method: 'POST',
      mode: 'cors',
      cache: 'no-store',
      credentials: 'include',
      headers: {
            'x-http-method-override': 'TRACE'
      }
} )
.then( ( response ) => response.text( ) ) 
.then( ( text ) => console.log( text ) ) 

You should now see the TRACE output, with the request headers, including cookies.

Great report!
As far as I understand, this only affects servers that do the x-http-method-override: TRACE thing?

Could you let us know who is working on the Chrome bug, so we coordinate with them on a fix?
I assume their proposed fix is along the lines of:

The TRACE method should be blocked in requests from fetch and XMLHttpRequest, whether it is in the main method parameter, or in common override headers ( 'x-http-method-override, x-http-method, x-http-override )

Exactly: if the server doesn't support the method override then it goes nowhere!

Just to add to the excitement though, there are three common override methods though:

  • x-http-method-override
  • x-http-method
  • x-method-override

The google team are currently haggling over which subteam gets the work, but as soon as they firm it up, I'll coordinate the details!

Assignee: nobody → smayya
Mentor: valentin.gosu
Severity: -- → S3
Flags: needinfo?(valentin.gosu)
Priority: -- → P1
Whiteboard: [necko-triaged]
Status: NEW → ASSIGNED
Attachment #9295420 - Attachment description: WIP: Bug 1790311 - add guard to block usage of unsafe methods in http override headers → WIP: Bug 1790311 - add guard to block usage of unsafe methods in http override headers. r=#necko
Attachment #9295420 - Attachment description: WIP: Bug 1790311 - add guard to block usage of unsafe methods in http override headers. r=#necko → Bug 1790311 - Block usage of unsafe methods in http override headers for fetch/xhr. r=#necko
Attachment #9295420 - Attachment description: Bug 1790311 - Block usage of unsafe methods in http override headers for fetch/xhr. r=#necko → WIP: Bug 1790311 - Block usage of unsafe methods in http override headers for fetch/xhr. r=#necko
Attachment #9295420 - Attachment description: WIP: Bug 1790311 - Block usage of unsafe methods in http override headers for fetch/xhr. r=#necko → Bug 1790311 - Block usage of unsafe methods in http override headers for fetch/xhr. r=#necko
Attachment #9295420 - Attachment description: Bug 1790311 - Block usage of unsafe methods in http override headers for fetch/xhr. r=#necko → WIP: Bug 1790311 - Block usage of unsafe methods in http override headers for fetch/xhr. r=#necko
Attachment #9295420 - Attachment description: WIP: Bug 1790311 - Block usage of unsafe methods in http override headers for fetch/xhr. r=#necko → Bug 1790311 - Block usage of unsafe methods in http override headers for fetch/xhr. r=#necko

Just so you know, it is looking like this will be pushed through as a change to the fetch spec: https://fetch.spec.whatwg.org/#forbidden-header-name

(In reply to scarlet from comment #11)

Just so you know, it is looking like this will be pushed through as a change to the fetch spec: https://fetch.spec.whatwg.org/#forbidden-header-name

Is there a PR for this on the repo?

Also, has the Chrome bug been assigned to anyone yet. It would be nice to sync with them deploying the fix.

Flags: needinfo?(martin.oneal)

No PR yet: do you chaps have contacts within WHATWG that can escalate it?

Thinking about it, there will likely be other headers that should also be on the forbidden list, like Max-Forwards too.

Flags: needinfo?(martin.oneal)

Maybe Anne can help with that.

Flags: needinfo?(annevk)

I created https://github.com/whatwg/fetch/security/advisories/GHSA-9hrx-wr8g-chvg to discuss this. (If you want to be added, I'll need your GitHub ID.)

scarlet, could you cc annevankesteren@gmail.com on the Chromium bug? Thanks!

Flags: needinfo?(annevk)

Thanks: my github is https://github.com/dramatic-bishop

I've asked the Chromium chaps to add you to the bug too.

Do you have a contact at Apple? There's a similar browser bug going through the system there, and it might be good to pull all the people together to get a consensus on the standard first, which should make synchronising the behaviour much easier.

Anne -is- our contact at Apple :-)

Haha, that makes things simple ;)

(In reply to Anne (:annevk) from comment #15)

I created https://github.com/whatwg/fetch/security/advisories/GHSA-9hrx-wr8g-chvg to discuss this. (If you want to be added, I'll need your GitHub ID.)

Anne could you please add me to Bug discussion?
My github ID is - MayyaSunil
Thanks in advance!

Sunil, done!

Everything progressing ok? Do you have an ETA for a release yet?

needinfo? for comment 21

Flags: needinfo?(valentin.gosu)
Flags: needinfo?(smayya)

(In reply to scarlet from comment #21)

Everything progressing ok? Do you have an ETA for a release yet?

I just checked with the other maintainers on the github issue, and it seems the other implementers are happy to follow close.
I'll be collaborating with Sunil on the WPT tests for this, and expect we'll be requesting sec-approval in the next couple of days.

Flags: needinfo?(valentin.gosu)

cool!

Attachment #9296476 - Attachment description: WIP: Bug 1790311 - add tests to check usage of unsafe methods with x-http-override headers for Fetch/XHR → Bug 1790311 - add tests to check usage of unsafe methods with x-http-override headers for Fetch/XHR. r=#necko
Flags: needinfo?(smayya)
Attachment #9295420 - Attachment description: Bug 1790311 - Block usage of unsafe methods in http override headers for fetch/xhr. r=#necko → Bug 1790311 - update handling of request headers in Fetch/XHR. r=#necko
Attachment #9296476 - Attachment description: Bug 1790311 - add tests to check usage of unsafe methods with x-http-override headers for Fetch/XHR. r=#necko → Bug 1790311 - update WPT tests for request headers in XHR/Fetch. r=#necko

Comment on attachment 9295420 [details]
Bug 1790311 - update handling of request headers in Fetch/XHR. r=#necko

Security Approval Request

  • How easily could an exploit be constructed based on the patch?: Based on the patch it is not straightforward to create an exploit.
  • Do comments in the patch, the check-in comment, or tests included in the patch paint a bulls-eye on the security problem?: No
  • Which older supported branches are affected by this flaw?: All
  • If not all supported branches, which bug introduced the flaw?: None
  • Do you have backports for the affected branches?: No
  • If not, how different, hard to create, and risky will they be?: It is straightforward to port to other branches.
    The severity is low.
  • How likely is this patch to cause regressions; how much testing does it need?: less likely as the code does not change any core behavior. It just introduces additional checks specific to this vulnerability.
  • Is Android affected?: Yes
Attachment #9295420 - Flags: sec-approval?
Attachment #9296476 - Flags: sec-approval?

Comment on attachment 9295420 [details]
Bug 1790311 - update handling of request headers in Fetch/XHR. r=#necko

Approved to land and request uplift. I am not sure what the policy is on WPT; I'm going to inquire if those should land now or we should hold them. Do you know if these WPT changes have been discussed or coordinated with Chrome?

Attachment #9295420 - Flags: sec-approval? → sec-approval+

(In reply to Tom Ritter [:tjr] from comment #26)

Comment on attachment 9295420 [details]
Bug 1790311 - update handling of request headers in Fetch/XHR. r=#necko

Approved to land and request uplift. I am not sure what the policy is on WPT; I'm going to inquire if those should land now or we should hold them. Do you know if these WPT changes have been discussed or coordinated with Chrome?

Thank you Tom for approving this. We have shared the WPT patch with Chrome.
We received a suggestion to add few more positive cases for the test.

Anne, what would you like to see as far as the WPT? Should we land them, or wait until the spec issue is public?

Flags: needinfo?(annevk)

I think landing them would be easier for other implementers. I personally don't think the risk here is big enough to warrant more complexity.

Flags: needinfo?(annevk)

Comment on attachment 9296476 [details]
Bug 1790311 - update WPT tests for request headers in XHR/Fetch. r=#necko

Thanks - approved to land!

Attachment #9296476 - Flags: sec-approval? → sec-approval+
Group: dom-core-security → core-security-release
Status: ASSIGNED → RESOLVED
Closed: 2 years ago
Resolution: --- → FIXED
Target Milestone: --- → 108 Branch

Landed: https://hg.mozilla.org/integration/autoland/rev/4b82c5a227c7e5c7ec692f552570fc6d61833920

Backed out for causing lint failures: https://hg.mozilla.org/integration/autoland/rev/8938aef1f835b98b1b4286e6f2cd15db3500193e

Push with failures: https://treeherder.mozilla.org/jobs?repo=autoland&group_state=expanded&selectedTaskRun=HEwY3ZiDTLKxSR5qkuOtLg.0&searchStr=linting%2Copt%2Cmisc%2Cchecks%2Csource-test-mozlint-wptlint-gecko%2Cw&revision=4b82c5a227c7e5c7ec692f552570fc6d61833920
Failure log: https://treeherder.mozilla.org/logviewer?job_id=394215547&repo=autoland
Failure lines:

TEST-UNEXPECTED-ERROR | /builds/worker/checkouts/gecko/testing/web-platform/tests/xhr/setrequestheader-header-forbidden.htm:74 | Whitespace at EOL (TRAILING WHITESPACE)
TEST-UNEXPECTED-ERROR | /builds/worker/checkouts/gecko/testing/web-platform/tests/xhr/setrequestheader-header-forbidden.htm:90 | Whitespace at EOL (TRAILING WHITESPACE)
TEST-UNEXPECTED-ERROR | /builds/worker/checkouts/gecko/tools/lint/wpt.yml:0 | Lint process exited with return code 2 (wpt)
Flags: needinfo?(smayya)

Comment on attachment 9295420 [details]
Bug 1790311 - update handling of request headers in Fetch/XHR. r=#necko

Beta/Release Uplift Approval Request

  • User impact if declined: Cross-Site-Tracing (XST) attack can be carried out on Servers implementing the TRACE method and supporting HTTP override headers.
  • Is this code covered by automated tests?: Yes
  • Has the fix been verified in Nightly?: No
  • Needs manual test from QE?: No
  • If yes, steps to reproduce:
  • List of other uplifts needed: None
  • Risk to taking this patch: Low
  • Why is the change risky/not risky? (and alternatives if risky): The changes does not change any core functional behavior. It adds an extra layer of validation of x-http-override/x-method-override/x-http-method headers for fetch/xhr. The impact is limited to these headers.
  • String changes made/needed:
  • Is Android affected?: Yes
Attachment #9295420 - Flags: approval-mozilla-beta?
Attachment #9296476 - Flags: approval-mozilla-beta?
Flags: needinfo?(smayya)
Flags: sec-bounty?

Comment on attachment 9295420 [details]
Bug 1790311 - update handling of request headers in Fetch/XHR. r=#necko

Approved for 107.0b6.

Attachment #9295420 - Flags: approval-mozilla-beta? → approval-mozilla-beta+

Comment on attachment 9296476 [details]
Bug 1790311 - update WPT tests for request headers in XHR/Fetch. r=#necko

Approved for 107.0b6.

Attachment #9296476 - Flags: approval-mozilla-beta? → approval-mozilla-beta+

Sunil, both patches graft cleanly to esr102. If you could add an esr uplift request when ready?

Flags: needinfo?(smayya)

Comment on attachment 9295420 [details]
Bug 1790311 - update handling of request headers in Fetch/XHR. r=#necko

ESR Uplift Approval Request

  • If this is not a sec:{high,crit} bug, please state case for ESR consideration: The bug exposed vulnerability in our code which can enable an attacker to carry out Cross-Site-Tracing (XST). The bug was serious enough to enforce a change in the current fetch specification.
  • User impact if declined: XST attack can be carried out on Servers implementing the TRACE method and supporting HTTP override headers.
  • Fix Landed on Version: 107.0b6
  • Risk to taking this patch: Low
  • Why is the change risky/not risky? (and alternatives if risky): The changes does not change any core functional behavior. It adds an extra layer of validation of x-http-override/x-method-override/x-http-method headers for fetch/xhr. The impact is limited to these headers.
Flags: needinfo?(smayya)
Attachment #9295420 - Flags: approval-mozilla-esr102?
Attachment #9296476 - Flags: approval-mozilla-esr102?
Flags: sec-bounty? → sec-bounty+

Thank you for reporting this issue. Although I don't believe this was in any way a browser bug, let alone a Firefox bug, this problem that web sites have brought upon themselves was clearly putting Firefox users in danger in some cases. In that light this fix makes users safer and we are awarding a security bug bounty for that.

Duplicate of this bug: 1797285

Comment on attachment 9295420 [details]
Bug 1790311 - update handling of request headers in Fetch/XHR. r=#necko

Approved for 102.5esr.

Attachment #9295420 - Flags: approval-mozilla-esr102? → approval-mozilla-esr102+

Comment on attachment 9296476 [details]
Bug 1790311 - update WPT tests for request headers in XHR/Fetch. r=#necko

Approved for 102.5esr.

Attachment #9296476 - Flags: approval-mozilla-esr102? → approval-mozilla-esr102+
Flags: qe-verify-
Whiteboard: [necko-triaged] → [necko-triaged][post-critsmash-triage]
Whiteboard: [necko-triaged][post-critsmash-triage] → [necko-triaged][post-critsmash-triage][adv-main107+]
Attached file advisory.txt
Whiteboard: [necko-triaged][post-critsmash-triage][adv-main107+] → [necko-triaged][post-critsmash-triage][adv-main107+][adv-esr102.5+]
Alias: CVE-2022-45411
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: