Closed Bug 1670763 Opened 4 years ago Closed 4 years ago

Firefox doesn't block "simple" cross-origin POST request

Categories

(Web Compatibility :: Site Reports, enhancement, P3)

enhancement

Tracking

(Not tracked)

RESOLVED INVALID

People

(Reporter: reymarkdivino, Unassigned)

References

(Blocks 1 open bug)

Details

(Keywords: reporter-external, Whiteboard: [reporter-external] [client-bounty-form] [verif?])

Hi Team,

The Cross-Origin Request Blocking are not functioning on Firefox browser,

Steps:
1.) Go to Chrome Browser and Open the Console tab using inspect now try to submit the request from fake origin http://139.162.100.143/upload_csrf_attack.html
2.) click the submit and you will see on Console and Network Tab that the Chrome are successfully blocking the request.

Now try to Firefox Browser
1.) Open Firefox and also open the Console and network tab, and navigate to fake origin http://139.162.100.143/upload_csrf_attack.html
2.) You will see on the Console tab the CORS errors BUT in network tab you will see a 200OK response means that the CSRF attack request are still going pass from Firefox CORS security.

Here is the PoC Video: https://firebasestorage.googleapis.com/v0/b/h1test-c0ae7.appspot.com/o/firefox%2Fpoc.mov?alt=media&token=f1904e20-5bfa-4c2e-b47d-fcbb646f257c

Flags: sec-bounty?

I'm afraid you're wrong - Chrome shows the response headers just fine if you click the "blocked" request, so the CSRF works in Chrome, too. If your server takes action upon receiving the request, you should not rely on CORS headers for CSRF protection. It doesn't work. Thinking through what you're doing, this should be obvious: the CORS header won't be received by the client (browser) unless it actually makes the request, ie it has to make the request to find out if the request is allowed. I'd say Chrome's UI is misleading here by pretending that the request is "blocked", when the only thing that is blocked is JS access to the request.

We can probably add some notification to the network tab to list that access to the CORS request from JS is blocked, in addition to the console warnings around this, but we should avoid doing exactly what Chrome is doing and show the same kind of "blocked" UI that we do when the request actually does not make it to the server (due to CSP, or an add-on blocking requests, or some other reason).

Group: firefox-core-security
Status: UNCONFIRMED → NEW
Type: task → defect
Component: Security → Netmonitor
Ever confirmed: true
Product: Firefox → DevTools
Summary: Cross-Origin Request Blocking are not functioning well on Firefox Browser → Network monitor does not show when requests are inaccessible to the site due to Cross-Origin Request Blocking

The devtools side of this looks like a regression, cf. bug 1638313. Honza?

Flags: needinfo?(odvarko)
Keywords: regression

Thanks Gijs for the triage!

(In reply to :Gijs (he/him) from comment #1)

We can probably add some notification to the network tab to list that access to the CORS request from JS is blocked, in addition to the console warnings around this, but we should avoid doing exactly what Chrome is doing and show the same kind of "blocked" UI that we do when the request actually does not make it to the server (due to CSP, or an add-on blocking requests, or some other reason).

Yes, agree.

(In reply to :Gijs (he/him) from comment #2)

The devtools side of this looks like a regression, cf. bug 1638313. Honza?

That bug only added platform support to identify requests "blocked" by CORS. The DevTools side wasn't completed (see bug 1640099).

So, let's use this bug to implement the notification.

  1. We could use similar UI as suggested for exposing anti-tracking classification flag in bug 1537627
  2. Or we could show an icon indicating "this request is inaccessible due to CORS" in the Status column (the same place where we show the Request Blocked icon)
  3. Or both

Honza

Blocks: 1484005
Severity: -- → S3
Type: defect → enhancement
Flags: needinfo?(odvarko)
Priority: -- → P3
Type: enhancement → defect
Keywords: regression
Summary: Network monitor does not show when requests are inaccessible to the site due to Cross-Origin Request Blocking → Network monitor should show when requests are inaccessible to the site due to Cross-Origin Request Blocking
Type: defect → enhancement

Hi Team, Thanks for the response and hope you guys are safe and doing well there.

This is my first time reporting on your platform.
Actually i came from Hackerone as you can see my profile https://hackerone.com/r3y

I reported this issue because of my report in one program on hackerone which is https://hackerone.com/logitech
I reported a CSRF attack on their 1 endpoint on logitech program which they implemented a CORS.

However when i try the CSRF attack on Chrome browser, the Chrome browser successfully block the csrf attack while on Firefox the csrf attack is successfully delivered,

They say that the issue is not from them, and this issue is from firefox, thats why i reported it here.

(In reply to Rey Mark from comment #4)

I reported a CSRF attack on their 1 endpoint on logitech program which they implemented a CORS.

However when i try the CSRF attack on Chrome browser, the Chrome browser successfully block the csrf attack while on Firefox the csrf attack is successfully delivered,

Can you link to the actual issue you reported against logitech? As it is, there are no details for us to be able to reproduce. The original issue as you filed it here suggests none of CORS is working in Firefox, and that is clearly not the case.

Still, if the CSRF is a true CSRF (that is, as soon as an attacker is able to make the request successfully, even without reading the response from the server, there is a security breach), then this is likely still an issue with logitech's endpoint. As I said in comment #1, the Chrome devtools show response headers from the server if you select the request as listed in their network console. Those response headers show that the request was made, even if the site making the request did not get access to the contents of the response. Normally, for a CSRF, this is not necessary - compromise occurs if the server acts on the request as if it was genuine, when it is not actually genuine.

(I'll hide this report again so details of the logitech issue do not become public)

Group: core-security-release
Flags: needinfo?(reymarkdivino)

Hi Gijs, Thank you so much for your response.

I can invite you on hackerone logitech report, just drop your email here.

I also export my report and uploaded it on my private dropbox. https://www.dropbox.com/s/y89a088n9cf9fte/HackerOne_Report-logitech%231004702.zip?dl=0

As your reference you can download my full report here https://www.dropbox.com/s/y89a088n9cf9fte/HackerOne_Report-logitech%231004702.zip?dl=0

Or if you want to view it on hackerone just drop your email here and i will invite you there.

I ask logitech if i can share my report to you and Logitech says: But please make sure to mark the report as confidential.

So please don't disclose any private information. Thank you so much.

Flags: needinfo?(reymarkdivino)

By the way the hackerone report link is https://hackerone.com/reports/1004702 but its private.

(In reply to Rey Mark from comment #6)

Hi Gijs, Thank you so much for your response.

I can invite you on hackerone logitech report, just drop your email here.

I created a hackerone account for gijskruitbosch at gmail (same as my bugmail on here but minus the "+bugs").

I also export my report and uploaded it on my private dropbox. https://www.dropbox.com/s/y89a088n9cf9fte/HackerOne_Report-logitech%231004702.zip?dl=0

Thanks. I don't understand logitech's response. They claim:

I think you may have modified the original CORS preflight request. The POST with credentials would trigger an OPTIONS request first that would have to answered with a 200OK allowing your IP address domain to proceed with the actual request.

I don't believe this is true. withCredentials on its own does not make a request not "simple", see https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Simple_requests . The request from your exploit looks like this:

        xhr.open("POST", "https:\/\/streamlabs.com\/api\/uploads", true);
        xhr.setRequestHeader("Accept", "*\/*");
        xhr.setRequestHeader("Accept-Language", "en-US,en;q=0.5");
        xhr.setRequestHeader("Content-Type", "multipart\/form-data; boundary=---------------------------2296378666846315172887480693");
        xhr.withCredentials = true;
        var body = "-----------------------------2296378666846315172887480693\r\n" + 
          "Content-Disposition: form-data; name=\"uploads[]\"; filename=\"xss.svg\"\r\n" + 
          "Content-Type: image/svg+xml\r\n" + 
          "\r\n" + 
          "snip\r\n" +
          "-----------------------------2296378666846315172887480693--\r\n";
        var aBody = new Uint8Array(body.length);
        for (var i = 0; i < aBody.length; i++)
          aBody[i] = body.charCodeAt(i); 
        xhr.send(new Blob([aBody]));

as far as I can tell this is going to be treated as a simple request, no preflight, because your method (POST), mimetype (multipart form data) and headers are allowed for simple requests. The screenshots that are in the zip file from the dropbox in Chrome also only show a POST request, no OPTIONS one. This is also what I see if I try the PoC myself in Chrome - and I get response headers when I select the request, indicating it was sent to the server (though my Chrome user has no existing data for streamlabs.com so I just get 302'd to their login page -- though in any case the hackerone issue says they've deployed a fix so presumably this is no longer exploitable).

So I think this is (was) a logitech issue.

Flags: needinfo?(reymarkdivino)

Hi Thanks for the response.

Hope you can help me explain your findings to them, because they are telling that this is Firefox issue BUT as you said this is not firefox issue.

Is this your email: gijskruitbosch+bugs@gmail.com

If that is your email i will invite you to the report and you can also post a comment there. Thank you so much!

Flags: needinfo?(reymarkdivino)

as i understand your email on hackerone is gijskruitbosch@gmail.com right ?

Hi Gijs

I think you may have modified the original CORS preflight request. The POST with credentials would trigger an OPTIONS request first that would have to answered with a 200OK allowing your IP address domain to proceed with the actual request.

I don't modify any original CORS preflight request. in fact i just did a burpsuite CSRF generator, to generate the CSRF attack.

I already invite you on my report using this email: gijskruitbosch@gmail.com

OK, thanks. I've commented on hackerone, curious what the logitech folks will say.

Honza: sorry, I guess we should split out the discussion of adding devtools UI to a new bug. If anything, the confusion around the Chrome UI from the hackerone report makes me think we should definitely not treat this the same as requests actually being blocked and not going to the server... I'll file a separate bug tomorrow; it's now pretty late here...

Flags: needinfo?(gijskruitbosch+bugs)

Hi Gijs, Thank you so much for the comment on hackerone report.

by the way I just confused here, You set my report here as P3 and S3 what does mean?, do you mean my bug are also valid here ?, I mean, I read it from the top and i think you guys are doing for improvement UI about CORS ?, Hope you can explain.

Again thank you so much for helping me out explaining your findings on my hackerone report.

Also just want to say sorry, because i doubled the filing of this kind of report, the other one is here https://bugzilla.mozilla.org/show_bug.cgi?id=1670762

That report https://bugzilla.mozilla.org/show_bug.cgi?id=1670762 is just the same of https://bugzilla.mozilla.org/show_bug.cgi?id=1670763 report

Thank you!

P3 and S3 mean priority and severity "normal", which means we're looking into it but it's not a critical issue. I think we're still trying to explore whether your bug is valid or not.

There are at least two things going on here:

  1. our DevTools UI might need improvement to clarify the situation. Even if our behavior is correct (and we're leaning that way) it appears to be confusing to Chrome users that we only show the CORS failures on the console and not the network tab.don't show the CORS failures on the network tab. On the other hand Chrome's UI is ambiguous about what "blocked" means -- people may assume it's the request (as in "Ad Blocker") but really it's the response. I don't work on our DevTools, but I agree w/Gijs (who also doesn't work on our DevTools) that this is worth considering. In comment 13 Gijs said he's going to file a separate bug for that.
  2. Do we have a CORS bug? We don't think so: we're following the spec as we understand it and behaving the same as Chrome (in terms of network traffic) based on our inspection of your testcase. But it's worrying that the Logitech folks (nice hardware, presumably smart folks) thought Firefox was wrong and it's worth double-checking that.

If Firefox is right and Logitech's understanding is wrong they may be making the same mistake elsewhere on their site.

OK, I filed bug 1671147 to continue the devtools netmonitor discussion.

I'm morphing this back to the original bug. I'll keep it confidential while working with logitech on the hackerone issue to ensure any/all endpoints with the relevant issue are fixed.

My discussion on the hackerone issue with logitech has strengthened my conviction this is not a Firefox issue - they were under the impression that setting withCredentials to true on an XHR request would result in a preflight request, but this is not the case in either Chrome or Firefox, and neither MDN nor the W3C's "for web developers" explainers nor the spec give me any reason to think this should be the case - cross origin form POST requests have always included cookies in the past, even without JS, so web sites should not rely on POST requests (with form-related or text/plain content mimetypes) getting preflighted.

As a result, I'm going to close this as invalid as it's not a Firefox bug. I'll try and respond to any remaining questions in the hackerone report if/when they come up. Reporter: thank you for your due diligence, and I hope that logitech ensure this is fixed in (all?) their endpoints. I obviously have no control over their bounty paying, though I hope they reconsider their decision...

Status: NEW → RESOLVED
Closed: 4 years ago
Component: Netmonitor → Desktop
Flags: needinfo?(gijskruitbosch+bugs)
Product: DevTools → Web Compatibility
Resolution: --- → INVALID
Summary: Network monitor should show when requests are inaccessible to the site due to Cross-Origin Request Blocking → Cross Origin Request Blocking / CSRF issues with logitech endpoint
Summary: Cross Origin Request Blocking / CSRF issues with logitech endpoint → Firefox doesn't block "simple" cross-origin POST request
Flags: sec-bounty? → sec-bounty-
Group: core-security-release
You need to log in before you can comment on or make changes to this bug.