Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-27570

Header injection with XHR newline in QNAM

    XMLWordPrintable

Details

    Description

      I noticed a potential issue when doing some QML/JS XMLHTTPRequest tests recently.

      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");
      and this results on the HTTP ===>
      ORIGIN: http://www.google.fi
      Referer: http://www.google.fi/whatever

      Qt/QNAM will apparently only construct one HTTP request, so I cannot use this to create a new, separate HTTP request.

      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 test 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.

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            shkearns Shane Kearns
            mikko saario Mikko Saario
            Votes:
            1 Vote for this issue
            Watchers:
            6 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes