Cenzic 232 Patent
Paid Advertising
web application security lab

Stopping CSRF With X-Headers (A Theory)

Billy Hoffman and I had a really interesting conversation at the WASC meetup yesterday and I thought I’d share the jist with you, because I think it really deserves more thought from a wider forum - we’re smart guys but I think you all could help out here in giving your thoughts. The concept is stopping CSRF using a modification to modern browsers that includes an X-Header to tell the website in question in which context the user is being sent to the function in question.

The Theory: The concept is you have an X-Header that that tells the website how the user got there. It may look something like this (as an example):

X-Request-Context: a_href

Okay, so the browser tells the machine that the user clicked on a link to end up there. Seems pretty benign. Now let’s look at an attack:

X-Request-Context: img_src

Looks pretty bad to me. Somehow the user ended up visiting the function through an image tag. Looks pretty suspicious doesn’t it? How would that ever happen in nature (except in the case where you have dynamically created images, or someone typos a URL). In the latter case, it’s still bad so don’t allow the function to fire. Gracefully die.

My initial retort: The next thing I thought of is how is this any different than fixing the Referer field? Why do we need a new technology to tell us that a user is coming from somewhere they shouldn’t? Granted, the Referer field doesn’t work. It’s a) not there all the time and b) can be spoofed. But what if we could fix those problems? Billy was hard pressed to come up with an answer, as was I. So I left the conversation be, and slept on it. Then I came up with a counter point.

My objection to my objection: There are situations where a function can be called from the correct page without the user meaning to. If I send the user to an otherwise benign page that has both a) a link to the function in question and b) an XSS hole, I can make the user have the correct Referer but the context would still look wrong:

X-Request-Context: iframe_src

Hmm… okay, so maybe request context is interesting afterall?

My counter-counter objection: So now all we need to know is that the context is valid. But wait, in the case of XSS it’s still possible for me to click on buttons in JavaScript. So even if the JavaScript on the page is invalid, both the Referer and the context would be correct:

X-Request-Context: form_submit

So it doesn’t look like that’s very bullet proof. Not to mention that a developer still would need to know to use this and code for it. That’s requires them to know what XSS and CSRF is, and if they already know that, there are probably better ways to mitigate this. I feel like my brain is spinning out of control here - I’m arguing with myself.

Some hope: Now let’s look at what I think MAY actually have some real value. Two technologies are giving us a lot of problems right now. XMLHTTPRequest and Flash. Both allow us to rewrite or add headers (depending on browsers and versions, yadda yadda). Both of those could provide their own context to allow us to know when they are being used. IE:

X-Request-Context: xmlhttprequest

Or…

X-Request-Context: flash

It’s very uncommon for users to want to allow XMLHTTPRequest unless they know that they are outputting some XML data. Likewise, when do you want a Flash page to link to you? Not too often, I’d say. So maybe there is some small incremental value in this technology concept, but I would rather debate it in an open forum.

7 Responses to “Stopping CSRF With X-Headers (A Theory)”

  1. Wladimir Palant Says:

    Interesting thing is: I looked at live.com today and noticed something very similar there. This application is mostly communicating with the server via XMLHttpRequest and it protects this communication against CSRF by adding the header “X-FPP-Command: 1″. The server will reject any request without this header so that you have no chance sending a fake request via images or hidden forms. Only XMLHttpRequest or Flash will work but those don’t work cross-domain.

  2. RSnake Says:

    Right, this would be almost exactly the opposite, where if they DID have that you would block them. But you’re right and that’s interesting.

  3. RSnake Says:

    Oh, and I forgot to mention, the comment about XMLHTTPRequest and Flash not being cross domain assumes there are no anti-DNS pinning attacks present. If there is, then those are still spoofable cross domain.

  4. Wladimir Palant Says:

    Well, they are using an X-Header to recognize where the request came from so that it is a similar idea. As to anti-DNS pinning: you are right of course. In particular, live.com will accept any value of the Host header (only once service on this IP) making this attack very easy. But on the other hand, the user won’t have his cookies - can you still do any harm in this situation?

  5. kuza55 Says:

    Its really a simple question we need to answer here; how is this better than session tokens (nonces)?

    Its probably a bit easier to implement, but still has all the normal problems, unless you’re going to start differentiating how things began, e.g. X-Request-Context: form_submit_js so that attackers cannot simply create the appropriate controls and send events to them without it getting noticed, in which case it would be much easier for web app developers to do defence in depth, because currently the only method I know of which stands any chance of stopping CSRF when you have an XSS hole is Stefan Esser’s idea of separating forms from the main site by domain boundaries, but its more complicated than it sounds: http://kuza55.blogspot.com/2007/01/on-stefan-essers-csrf-protection-idea.html But even then; its still much easier than rewriting browser code.

    And then you also need to take into consideration how much work and re-designing needs to be done on the browser side.

    And given the fact that it will most likely not be widely adopted as a CSRF protection measure, because you still need all browsers to implement it (which I doubt will happen, ever), and all 3rd party app developers, etc.

    I just think the whole philosophy behind it is wrong; its essentially saying that you need someone else to fix your security issues; sure they stem from browser issues, but its the platform you chose to build your application on; you need to work with it, rather than constantly trying to get it to change the way you want it to. Or then again, I could be wrong; this is just my view, *shrug*.

  6. Kishor Says:

    I had discussed a similar technique here
    http://wasjournal.blogspot.com/2006/12/csrf-protection-for-ajax-area-of-web.html

  7. RSnake Says:

    Good writeup, Kishor, but yah, it suffers from all the problems above. No matter how you slice it, this is a tough problem.