Issue metadata
Sign in to add a comment
|
Security: missing preflight for XHR with credentials when Content-Type header is malformed
Reported by
ivan.rum...@gmail.com,
Mar 28 2018
|
||||||||||||||||||||||
Issue description
VULNERABILITY DETAILS
To prevent CSRF via ajax-requests there are some restrictions. In general you cannot achieve anything bigger than sending the same request via <form> tag. In <form> you are able to send POST request only with 3 Content-Type headers: multipart/form-data, text/plain, application/x-www-form-urlencoded. For example <.. enctype="text/plain" charset="UTF-8">. Anything suspisious in enctype attribute will force request to be sent with application/x-www-form-urlencoded header value, so if you try to <.. enctype="text/plain, qweqwe"> the request's Content-Type will be application/x-www-form-urlencoded. Finally Content-Type structure from <form> tag looks like:
Content-Type: <strict enctype value>;<charset value> (no commas allowed)
But if you try to send XHR in Chrome with xhr.setRequestHeader('Content-Type', 'text/plain, QWEQWEQWEQWEQWETEST;charset=UTF-8'); with credentials it will be sent without preflight.
However, this scenario works only because Chrome allows two delimiters between type/subtype and parameters - ";" and ","
Why is it dangerous?
First, it violates RFC which has defined Content-Type structure
"Content-Type" ":" type "/" subtype *(";" parameter) - no comma separates, strict ";"
Second, some parsers may strangly interpret malformed Content-Type as application/octet-stream, and since such XHR request will work without preflight even with credentials, it will allow to have one more potential Content-Type for performing CSRF attack.
Finally forcing user to send XHR with custom Content-Type is dangerous in XSS context since you can easily make Content-Type: text/plain, <iframe src=x onload=alert()>;charset=UTF-8
VERSION
Chrome Version: stable
Operating System: Win 10 latest
REPRODUCTION CASE
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://google.com", true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded, MYSTUFFHERE, application/json, application/octet-stream;charset=UTF-8');
xhr.withCredentials = true;
xhr.send();
Tested also in firefox - it sends preflight if "," character comes after type/subtype
,
Mar 28 2018
,
Dec 18
This bug has been closed for more than 14 weeks. Removing security view restrictions. For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot |
|||||||||||||||||||||||
►
Sign in to add a comment |
|||||||||||||||||||||||
Comment 1 by elawrence@chromium.org
, Mar 28 2018Labels: Security_Impact-Stable
Status: Untriaged (was: Unconfirmed)