Cross-Origin restriction bypass with fetch using 302 redirection

RESOLVED DUPLICATE of bug 1212669

Status

()

Core
DOM
RESOLVED DUPLICATE of bug 1212669
2 years ago
8 months ago

People

(Reporter: Abdulrahman Alqabandi, Assigned: bkelly)

Tracking

({csectype-sop, sec-high})

41 Branch
csectype-sop, sec-high
Points:
---
Bug Flags:
sec-bounty +

Firefox Tracking Flags

(firefox41 affected, firefox42 affected, firefox43 unaffected, firefox44 unaffected, firefox-esr38 unaffected)

Details

(Whiteboard: fixed on trunk as part of bug 1184607, rediscovered as 1212669)

Attachments

(4 attachments)

(Reporter)

Description

2 years ago
Created attachment 8665773 [details]
PoC-FF.html

User Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:42.0) Gecko/20100101 Firefox/42.0
Build ID: 20150921151815

Steps to reproduce:

1. Create a 302 redirect on owned server (http://evil.guy/redir) which contains a 'Location:' header pointing to the victims website  (ex: Location: https://twitter.com/)

2. Create page (http://evil.guy/PoC.html) that contains the exploit code as well as two iframes, one empty and one pointing to '//twitter.com/' directly. (please see attached PoC-FF.html)

3. Modify 'PoC-FF.html' replacing 'http://localhost/redir.php' with your own 302 redirector.

4. Visit 'http://evil.guy/PoC-FF.html' 



Actual results:

- The iframe with href='//twitter.com/' is immediately blocked (as expected)
- The second iframe, however, contains the full contents of twitter.com

If the victim was logged into twitter then the iframe will display him as logged in, successfully bypassing firefox's Cross-Origin security, as you can probably imagine, this is extremely unsafe for FireFox users.


Expected results:

Both iframes should have been blocked. 

More precisely, the Fetch() function should not blindly follow 302 redirects but rather detect if a 302 is present then recheck origins.
(Reporter)

Updated

2 years ago
Severity: normal → critical
Keywords: csectype-sop, sec-high
(Reporter)

Comment 1

2 years ago
P.S. Tested on Firefox 41.0 and it works.
(Reporter)

Comment 2

2 years ago
Created attachment 8665819 [details]
PoC using the same bug to extract value of hidden input elements

This PoC is designed to extract twitters 'authenticity_token' value through the iframe despite the input being type=hidden. Proof this can be used to leak sensitive user data from external website.
This effects almost any website.
Group: firefox-core-security → core-security
Component: Untriaged → DOM
Product: Firefox → Core

Comment 3

2 years ago
Nikhil, I'm having trouble figuring out what the spec expects us to do for a no-cors fetch that receives a redirect status to a cross-origin URL. I guess the idea is that the redirection is allowed, but the result should be an opaque filtered response?
Reporter, please do not assign security keywords. That is a job for Mozilla staff.
Severity: critical → normal
Flags: sec-bounty?
Keywords: csectype-sop, sec-high
(In reply to Josh Matthews [:jdm] from comment #3)
> Nikhil, I'm having trouble figuring out what the spec expects us to do for a
> no-cors fetch that receives a redirect status to a cross-origin URL. I guess
> the idea is that the redirection is allowed, but the result should be an
> opaque filtered response?

That is correct.
I can't reproduce the steps outlined. Neither of the iframes load and the fetch() call clearly returns an opaque response. The blob is logged as size 0 and empty and creating a URL from that should lead to an empty blob. both frames remain empty for me. Using Mozilla/5.0 (X11; Linux x86_64; rv:44.0) Gecko/20100101 Firefox/44.0 ID:20150923030230 CSet: 19b4265d0d568d232fb3a34705f947b6db7496dc
uploading my test case in case i did something wrong.
Created attachment 8666149 [details]
node server that serves file and redirect.

the poc-ff.html should be saved in the same folder as the server. modify the redir path to be localhost:8080/redir.

Comment 9

2 years ago
Can you reproduce this in FF 43 or 44?
Flags: needinfo?(qab)
(Reporter)

Comment 10

2 years ago
(In reply to Nikhil Marathe [:nsm] (No longer reading bugmail, please needinfo?) from comment #8)
> Created attachment 8666149 [details]
> node server that serves file and redirect.
> 
> the poc-ff.html should be saved in the same folder as the server. modify the
> redir path to be localhost:8080/redir.

I used a simple php file with the following:
<?header('Location: https://twitter.com/');?>

Also, I tested these on FF41 and FF42 beta, I see that you are using v44 which I have not tested on. (nor am I sure I can get v44)
I will upload a screenshot (using v41) and displaying the exact response retrieved among other things.

Also in case it matters, Im using Windows 8.1 64bit
Flags: needinfo?(qab)
(Reporter)

Comment 11

2 years ago
Created attachment 8666154 [details]
Environment screenshot
(Reporter)

Comment 12

2 years ago
(In reply to Josh Matthews [:jdm] from comment #9)
> Can you reproduce this in FF 43 or 44?

Not yet, checking now.
You can get 44 from nightly.mozilla.org.
(Reporter)

Comment 14

2 years ago
(In reply to Josh Matthews [:jdm] from comment #13)
> You can get 44 from nightly.mozilla.org.

Yes I can confirm the bug does not seem to work on v43 or v44. Fetch is indeed returning an opaque response in both.

Updated

2 years ago
status-firefox41: --- → affected
status-firefox42: --- → affected
status-firefox43: --- → unaffected
status-firefox44: --- → unaffected
Whiteboard: fixed on trunk, possible dupe? fix-range-wanted
Group: core-security → dom-core-security
This is somewhat similar to bug 1111834 fixed in Firefox 37, for regular CORS though, not using fetch().

May have been fixed by bug 1199049? (see also bug 1199693) Bug 1194384 was duped to that one and seems particularly on point here ("Fetch event interception and CORS preflight requests are backwards"). If that was the fix it looks way too involved to backport to 42.

Josh: does this look like a dupe of your bug 1194384?
Flags: needinfo?(josh)
(Reporter)

Comment 16

2 years ago
I don't know if this matters by now, but this only works with {mode: 'no-cors'} passed to the fetch() function.
I just tried a mozilla-central build for 9/12 and can't reproduce the problem, so bug 1199049 does not seem to be the fix.
Flags: needinfo?(josh)
It's present in http://ftp.mozilla.org/pub/firefox/nightly/2015/09/2015-09-01-mozilla-central-debug/ and not present in http://ftp.mozilla.org/pub/firefox/nightly/2015/09/2015-09-02-mozilla-central-debug/, so http://hg.mozilla.org/mozilla-central/pushloghtml?startdate=2015-08-31&enddate=2015-09-02 suggests that it's bug 1184607.
Assignee: nobody → bkelly
Status: UNCONFIRMED → NEW
status-firefox-esr38: --- → unaffected
Ever confirmed: true
Keywords: csectype-sop, sec-high
Whiteboard: fixed on trunk, possible dupe? fix-range-wanted → fixed on trunk as part of bug 1184607
Version: 42 Branch → 41 Branch
(Assignee)

Comment 19

2 years ago
I already have patches for this up in bug 1212669.  Do I need to move them over here?
Depends on: 1212669

Comment 20

2 years ago
Sure, but it doesn't matter much either way.
(Assignee)

Comment 21

2 years ago
I'm just going to land the patches in bug 1212669.

Updated

2 years ago
Status: NEW → RESOLVED
Last Resolved: 2 years ago
Resolution: --- → DUPLICATE
Duplicate of bug: 1212669
Flags: sec-bounty? → sec-bounty+
Whiteboard: fixed on trunk as part of bug 1184607 → fixed on trunk as part of bug 1184607, rediscovered as 1212669
(Assignee)

Updated

2 years ago
Depends on: 1214361
(Assignee)

Updated

2 years ago
No longer depends on: 1214361
This vulnerability will be identified as CVE-2015-7184
Group: dom-core-security
You need to log in before you can comment on or make changes to this bug.