9

I have been reading on fixing CSRF attacks. From some research I understand that checking for a non-standard header would prevent CSRF attacks since the browser will not automatically send such headers.

So I was assuming to recommend using Authorization: Bearer tokens for the ASP application I am currently testing. Since this this header value won't be sent by the browser itself, I am assuming this approach would fix CSRF issue. But then I came to notice a stack overflow question which confused me a little. The answer still recommends to use the CSRF tokens.

So, basically I have two questions.

  1. Would this approach actually work to prevent CSRF attacks?
  2. I know If I am vulnerable to XSS attacks my cookies can be read and the bearer tokens can be stolen. But can the injected XSS create a the Authorization: Bearer header and append the stolen value from cookie?
Anders
  • 64,406
  • 24
  • 178
  • 215
Anonymous Platypus
  • 1,392
  • 3
  • 18
  • 33

2 Answers2

11

Would this approach actually work to prevent CSRF attacks?

Yes. An attacker can't make a browser send a request that include the authorization header with the correct bearer token. This is for two reasons:

  • The attacker can't set the authroization header.
  • The attacker don't know the correct value of the token, so they wouldn't know what to set it to.

However, this might be sensitive to changes in your application. For instance, if someone one day decides to change the authentication system to something cookie based, they may not realize that they are disabling your CSRF protection by doing that.

Also, in the case where the required header value is predictable, a CORS policy that allows that header to be set could spell trouble.

As for the linked SO question, I am not sure I understand the accepted answer. But if you look at the second answer, your situation is of type #2 and not type #1.

I know If I am vulnerable to XSS attacks my cookies can be read and the bearer tokens can be stolen. But can the injected XSS create a the Authorization: Bearer header and append the stolen value from cookie?

Yup, you could do that if you can inject code.

If you have an XSS vulnerability, it will allow the attacker to bypass any CSRF protection you put in place. So concerns for XSS can't really be used to favor one form of CSRF protection over another - in the face of XSS they are all void.

A slight difference here is that your token cannot be marked as HTTP-only, since you need to access it from JS to put it in the header. Consequently, an XSS attacker can steal it and then conveniently send requests from her own computer. If the authentication token is HTTP-only the attacker has to make the injected code send the requests, which is a bit of a hassle but not impossible.

RJFalconer
  • 293
  • 1
  • 7
Anders
  • 64,406
  • 24
  • 178
  • 215
4

It can work, but XSS will compromise the session completely.

The Intent of CSRF mitigations is to limit the scope of who can submit data from a user's browser to the server and cause something to happen. CSRF attacks work by relying on the special properties of web browsers in that they generally include cookies in all requests and the attacker just needs to get the browser to send a request to the target URL. You mitigate this by making the request include data that isn't part of the request normally sent by the browser; e.g. a custom header or form field, injected by JavaScript.

A bearer token in the Authorization header necessarily requires being added by JavaScript because the browser will never include it (barring NTLM/Nego/etc, but that's another topic). So that fits the requirement set out above reasonably well.

The catch is that any JavaScript executed on that page can do the exact same thing as your code adding the header because there are no security boundaries here. That means you're hosed by any form of XSS that allows for arbitrary code execution. And in fact, it puts you in a weaker position because they can just steal your token and do whatever they want with it outside the bounds of a browser, whereas a protected cookie can't be stolen because it's not accessible by JavaScript.

So... you're safe if you can prevent XSS completely, but that's a difficult task under the best circumstances. That said, adding a cookie into the mix doesn't necessarily help because XSS can generate requests that add the token, and the browser will still happily include the cookie.

Steve
  • 15,155
  • 3
  • 37
  • 66
  • 3
    Isn't all CSRF protections vulnerable to XSS? So it's not really an argument for picking one method over another. – Anders Nov 01 '17 at 14:20
  • @Anders most things are vulnerable to XSS. It's just a matter of how bad the effects of it are. – Steve Nov 01 '17 at 14:49
  • @anders: yes and no. yes, xss renders csrf protection useless. no, it's no longer "CS"; xss runs locally. it's actually not even a forgery at that point, more of a hijacking. – dandavis Nov 02 '17 at 03:59
  • 1
    So, I should conclude the best approach as follows: Setup CSRF tokens and keep the session identifier in a HttpOnly cookie. Am I correct? – Anonymous Platypus Nov 03 '17 at 11:44