12

I want to protect my application against XSRF. Although I couldn't really understand what the problem is and how my solution works, after some research I came up with a solution, which Angular uses. As far as I got, my solution requires the following steps:

  • Client sends a request for my SPA.
  • I send XSRF-token (not HTTP-only so that JS will be able to read it). I also save this XSRF-token to the users session on the server.
  • For every POST request I want my client to read the XSRF-token and set a X-XSRF-TOKEN header to this token.
  • I'll check every request by checking if the request header and the user session XSRF-token match. If they do, I'll also check JWT for authentication if I need.
  • After validating the XSRF-token, I'll make changes to the database. Also I'll change XSRF-token again, and send the new token to the user, and change token for the session.

But I am not sure how this helps, if I have a XSS vulnerability, since any injected JavaScript code could also do the same. I want to understand the problem and how such a solution helps.

FYI, I am also implementing JWT based authentication, using Redis for session management, on an Express server.

Anders
  • 64,406
  • 24
  • 178
  • 215
FurkanO
  • 223
  • 1
  • 2
  • 6
  • CSRF is a serious and easy to exploit security vulnerability. Better read about it (and what same origin policy covers and doesn't cover in general) before attempting to invent "solutions". – billc.cn Jun 14 '16 at 17:23
  • 1
    is my implementation invalid ? – FurkanO Jun 14 '16 at 17:25

1 Answers1

10

Is the plan good?

Your plan looks good to me. Using a CSRF-token is the standard solution to this kind of problem. But you should not feel safe just because some stranger on the internet tells you it looks good - make sure you understand what you are doing and why, otherwise your are bound to make mistakes.

(A minor point: I am not sure you need to change the token at every request.)

So why does it work?

From this old answer of mine:

The attacker fools the victim to visit http://evil.com that contains a form that automatically does a POST to http://bank.com/transfer?to=evilHacker&amount=1000000. If the victim is already logged in to her bank, the cookie with the session ID will be sent like usual by the browser and there is no way for the bank server to know that the victim did not actually intend to transfer the money. Note that this relies on the browser sending the cookie with the session ID to bank.com.

So how can a CSRF-token help? If the bank.com always checks that a random token unique to that session is present in the request, evil.com can not forge the request since the evil hacker running that site does not know what the token is.

But what about XSS?

As you say in your question, this will not help if there is an XSS vulnerability. In fact, there is no CSRF protection that will help in that case, but if you are vulnerable to XSS you have bigger problems than stolen CSRF-tokens to worry about anyway.

So the only thing to do here is to work on your XSS protection.

Anders
  • 64,406
  • 24
  • 178
  • 215
  • 3
    re: change token at each request. No, you don't need to. " A CSRF token should be unique per user session, large random value, and also generated by a cryptographically secure random number generator. " per https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.md – Elroy Flynn Jul 11 '19 at 02:51