Generic CORS bypass that enables Cross-Site-Tracing (XST)
Categories
(Core :: DOM: Networking, defect, P1)
Tracking
()
People
(Reporter: martin.oneal, Assigned: smayya, Mentored)
References
Details
(4 keywords, Whiteboard: [necko-triaged][post-critsmash-triage][adv-main107+][adv-esr102.5+])
Attachments
(3 files)
48 bytes,
text/x-phabricator-request
|
dmeehan
:
approval-mozilla-beta+
dmeehan
:
approval-mozilla-esr102+
tjr
:
sec-approval+
|
Details | Review |
48 bytes,
text/x-phabricator-request
|
dmeehan
:
approval-mozilla-beta+
dmeehan
:
approval-mozilla-esr102+
tjr
:
sec-approval+
|
Details | Review |
651 bytes,
text/plain
|
Details |
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.
Comment 3•2 years ago
|
||
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...
The Google chromium ticket is here: https://bugs.chromium.org/p/chromium/issues/detail?id=1362331
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).
Updated•2 years ago
|
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.
Comment 7•2 years ago
|
||
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!
Updated•2 years ago
|
Assignee | ||
Updated•2 years ago
|
Assignee | ||
Comment 9•2 years ago
|
||
Updated•2 years ago
|
Updated•2 years ago
|
Updated•2 years ago
|
Updated•2 years ago
|
Updated•2 years ago
|
Updated•2 years ago
|
Assignee | ||
Comment 10•2 years ago
|
||
Depends on D157729
Reporter | ||
Comment 11•2 years ago
|
||
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
Comment 12•2 years ago
|
||
(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.
Reporter | ||
Comment 13•2 years ago
|
||
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.
Comment 15•2 years ago
|
||
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!
Reporter | ||
Comment 16•2 years ago
|
||
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.
Comment 17•2 years ago
|
||
Anne -is- our contact at Apple :-)
Reporter | ||
Comment 18•2 years ago
|
||
Haha, that makes things simple ;)
Assignee | ||
Comment 19•2 years ago
•
|
||
(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!
Comment 20•2 years ago
|
||
Sunil, done!
Reporter | ||
Comment 21•2 years ago
|
||
Everything progressing ok? Do you have an ETA for a release yet?
Updated•2 years ago
|
Updated•2 years ago
|
Comment 22•2 years ago
|
||
needinfo? for comment 21
Comment 23•2 years ago
|
||
(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.
Reporter | ||
Comment 24•2 years ago
|
||
cool!
Updated•2 years ago
|
Assignee | ||
Updated•2 years ago
|
Updated•2 years ago
|
Updated•2 years ago
|
Assignee | ||
Comment 25•2 years ago
|
||
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
Assignee | ||
Updated•2 years ago
|
Comment 26•2 years ago
|
||
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?
Assignee | ||
Comment 27•2 years ago
|
||
(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=#neckoApproved 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.
Comment 28•2 years ago
|
||
Anne, what would you like to see as far as the WPT? Should we land them, or wait until the spec issue is public?
Comment 29•2 years ago
|
||
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.
Comment 30•2 years ago
|
||
Comment on attachment 9296476 [details]
Bug 1790311 - update WPT tests for request headers in XHR/Fetch. r=#necko
Thanks - approved to land!
![]() |
||
Comment 31•2 years ago
|
||
update handling of request headers in Fetch/XHR. r=necko-reviewers,valentin
https://hg.mozilla.org/integration/autoland/rev/7c8a24ef4a8339190e8daea55e99ce3ca4ff1d47
https://hg.mozilla.org/mozilla-central/rev/7c8a24ef4a83
![]() |
||
Comment 32•2 years ago
|
||
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)
Assignee | ||
Comment 33•2 years ago
|
||
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
Assignee | ||
Updated•2 years ago
|
Assignee | ||
Updated•2 years ago
|
Updated•2 years ago
|
Updated•2 years ago
|
![]() |
||
Comment 34•2 years ago
|
||
update WPT tests for request headers in XHR/Fetch. r=necko-reviewers,valentin
https://hg.mozilla.org/integration/autoland/rev/9078a8c3aa648c9d24f867655a88ac5db0810108
https://hg.mozilla.org/mozilla-central/rev/9078a8c3aa64
Comment 35•2 years ago
|
||
Comment on attachment 9295420 [details]
Bug 1790311 - update handling of request headers in Fetch/XHR. r=#necko
Approved for 107.0b6.
Comment 36•2 years ago
|
||
Comment on attachment 9296476 [details]
Bug 1790311 - update WPT tests for request headers in XHR/Fetch. r=#necko
Approved for 107.0b6.
Comment 37•2 years ago
|
||
uplift |
https://hg.mozilla.org/releases/mozilla-beta/rev/2f787b9f88a4
https://hg.mozilla.org/releases/mozilla-beta/rev/e27520f90e7a
Comment 38•2 years ago
|
||
Sunil, both patches graft cleanly to esr102. If you could add an esr uplift request when ready?
Assignee | ||
Comment 39•2 years ago
|
||
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.
Assignee | ||
Updated•2 years ago
|
Updated•2 years ago
|
Comment 40•2 years ago
|
||
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.
Comment 42•2 years ago
|
||
Comment on attachment 9295420 [details]
Bug 1790311 - update handling of request headers in Fetch/XHR. r=#necko
Approved for 102.5esr.
Comment 43•2 years ago
|
||
Comment on attachment 9296476 [details]
Bug 1790311 - update WPT tests for request headers in XHR/Fetch. r=#necko
Approved for 102.5esr.
Comment 44•2 years ago
|
||
uplift |
Updated•2 years ago
|
Updated•2 years ago
|
Comment 45•2 years ago
|
||
Updated•2 years ago
|
Updated•2 years ago
|
Updated•2 years ago
|
Updated•9 months ago
|
Description
•