[Development] Newlines in XHR / QNetworkAccessManager headers

Mikko.Saario at nokia.com Mikko.Saario at nokia.com
Sun Oct 7 23:23:53 CEST 2012


Hello,

I noticed a potential issue when doing some QML/JS XMLHTTPRequest tests recently. The "issue" is quite simple as explained below and I would like to know what the Qt developer community thinks about it - whether it is a "vulnerability" or perhaps just a "feature".

So I was using QML and as far as I can tell it uses the QNetworkAccessManager to construct the HTTP requests. As we know, the usual way of adding headers to an XHR is:



xhr.setRequestHeader("Header","Value");



I wanted to check out messing with the "forbidden" headers that have a security significance (because I know a definite misuse case for it), such as Origin or Referer. So you are not supposed to be able to add or modify these in JavaScript for obvious reasons.



First of all, I can add an Origin header in JavaScript (well I guess this particular header really "came about" with XHR v2 / CORS so perhaps just is not "supported" or blacklisted as such yet):



xhr.setRequestHeader("Origin","http://www.google.fi");

results on the HTTP request ==>

ORIGIN: http://www.google.fi



That's one debatable issue, but perhaps there is another more interesting case (at least in my opinion). I can also add newlines ("\n" or "\r\n") and thus spoof any header, even without that all-caps shouting. This time I added the new stuff (still in QML + JS) into the value side of the header (also works on the Header part, but then it's all caps [which I suppose should not make a difference really]) (interestingly, this attack vector did not succeed when I tried supplying malicious input via QML TextInput, as the newlines were printed as "\n" [which is good - a header value something\nReferer:abc is of no use for an attacker]):



xhr.setRequestHeader("Origin","http://www.google.fi\nReferer: http://www.google.fi/whatever<http://www.google.fi/nReferer:%20http:/www.google.fi/whatever>");

and this results on the HTTP ===>

ORIGIN: http://www.google.fi
Referer: http://www.google.fi/whatever



I found Mozilla discussed and apparently fixed a similar, but somewhat wider and more damaging issue back in 2005 (Qt case is less severe as the Qt/QNAM will apparently only construct one HTTP request, instead of Firefox back then sending multiple HTTP requests if you ended the first HTTP request with newlines and created a second HTTP request):

https://bugzilla.mozilla.org/show_bug.cgi?id=297078



Here are the (current) specs for XHR I found - listing the headers that should not be added programmatically:

http://xhr.spec.whatwg.org/#the-setrequestheader()-method

http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader-method



I tried this same on Firefox and Chrome (for Win7), they will both fail as expected. Another test I made was using the QML browser demo found in the SDK that uses the Webkit WebView - this fails as well (i.e. works as intended). In that case I loaded a HTML/JS page into the WebView that performed the XHR. And as said earlier, the newlines were rendered as string "\n" when I used a QML TextInput - which is good. And yes, "same origin" is the target as spoofing Host has no effect, but in case of localhost, that could be anything running locally.



Small bug or something else?


Mikko Saario

PS My Qt is SDK 1.2.1 with Qt 4.8.1

----------------------------
Axel Oxenstierna - a Swedish nobleman - in 1648, in a letter to his son: "An nescis, mi fili, quantilla prudentia mundus regatur?"

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/development/attachments/20121007/c0f5ee10/attachment.html>


More information about the Development mailing list