Closed
Bug 1211020
Opened 9 years ago
Closed 9 years ago
FF is not Executing CORS Preflight for Cross Domain XHR POST if Content-Type includes text/plain (but is not actually text/plain)
Categories
(Core :: DOM: Security, defect)
Tracking
()
RESOLVED
DUPLICATE
of bug 1210302
People
(Reporter: charles_overbeck, Unassigned)
Details
(Keywords: csectype-sop, sec-high)
Attachments
(1 file)
537 bytes,
text/html
|
Details |
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36 Steps to reproduce: - Opened the attached file crossdomainpost.html in Firefox, which does a cross-domain POST to http://www.google.com. I tried opening it both using the file uri and serving it from a local web server. - Opened Web Developer | Network so I can see network calls from the browser - Clicked the Submit Request button Actual results: FireFox executed the POST (the request failed with a 405 response, but that's irrelevant for purposes of this bug). Expected results: Since this is a cross-domain POST, FireFox should have first executed an OPTIONS to see if the resource supports CORS. Since the OPTIONS for that resource returns a 405, it should have never proceeded to execute the POST. Both Chrome and Safari execute OPTIONS and don't proceed any further. Didn't try IE, since I'm not on Windows.
Reporter | ||
Updated•9 years ago
|
Component: Untriaged → Security
OS: Unspecified → Mac OS X
Reporter | ||
Comment 1•9 years ago
|
||
Just realized that in the my example html, this line is significant: xhr.setRequestHeader("Content-Type", "application/json, text/plain, */*, charset=utf-8"); This is not a valid Content-Type, per http://greenbytes.de/tech/webdav/rfc2616.html#rfc.section.14.17, but it goes through. According to https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests, text/plain requests are not pre-flighted. If I remove the "text/plain" portion of the Content-Type, then the request does get preflighted -- an OPTIONS call is made. However, when I view the request in my web server, it gets interpreted as application/json. The combination of FireFox treating the request as text/plain and my server treating it as application/json make my web app vulnerable to CSRF.
Reporter | ||
Updated•9 years ago
|
Summary: FF is not Executing CORS Preflight for Cross Domain XHR POST → FF is not Executing CORS Preflight for Cross Domain XHR POST if Content-Type includes text/plain (but is not actually text/plain)
Updated•9 years ago
|
Group: core-security
Flags: sec-bounty?
Comment 2•9 years ago
|
||
Confirmed, and you can see the comment 1 behavior by comparing the attached testcase (which won't work loaded from BMO unless you disable mixed-content blocking) to data:text/html,<html><body><script>function%20submitRequest(){var%20xhr%20=%20new%20XMLHttpRequest();xhr.open("POST",%20"http://www.google.com");xhr.setRequestHeader("Accept",%20"application/json,%20text/plain,%20*/*");xhr.setRequestHeader("Content-Type",%20"application/json,%20*/*,%20charset=utf-8");xhr.send('{"hello":"world"}');}</script><form%20action="%23"><input%20type="button"%20value="Submit%20request"%20onclick="submitRequest();"%20/></form></body></html> We seem to be doing the right thing in nsContentUtils::IsAllowedNonCorsContentType() (called from xhr code), that is, checking for the literal type rather than a substring match: http://mxr.mozilla.org/mozilla-central/source/dom/base/nsContentUtils.cpp#7194 The above routine underlies the places that check in both XHR and Fetch code. net_ParseRequestContentType() also seems to be doing the right thing -- if it finds a ',' in the header it returns an empty value. Is someone not checking for this? but an empty string is never going to positively match "text/plain". When we send the header (in the case where we bypass the pre-flight) we definitely have the comma-separated list. FWIW I tested the other two "safe" content-types, "application/x-www-form-urlencoded" and "multipart/form-data", and got the same behavior: no pre-flight if they're present, pre-flight if they aren't. "text/plain" will trigger simple-header behavior if it's followed by a space or comma, you can put anything you want after that point. "text/plainish" won't work, "text/plain ish" will. If there is something in front of "text/plain" then it must be delimited by a comma (and optional space). You can't use only space in front like you can after.
Group: core-security → dom-core-security
Status: UNCONFIRMED → NEW
Component: Security → DOM: Security
Ever confirmed: true
Product: Firefox → Core
Comment 3•9 years ago
|
||
dup of 1210302?
Comment 4•9 years ago
|
||
Does this still reproduce? We fixed bug 1210302 in Firefox 42 and this may be a duplicate of that reported issue.
Flags: needinfo?(charles_overbeck)
Reporter | ||
Comment 5•9 years ago
|
||
It no longer reproduces in Firefox 42 -- it is fixed.
Updated•9 years ago
|
Status: NEW → RESOLVED
Closed: 9 years ago
Flags: needinfo?(charles_overbeck)
Resolution: --- → DUPLICATE
Updated•9 years ago
|
Flags: sec-bounty? → sec-bounty-
Updated•8 years ago
|
Group: dom-core-security
Updated•8 years ago
|
Keywords: csectype-sop,
sec-high
You need to log in
before you can comment on or make changes to this bug.
Description
•