Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do I need a CSRF token for jQuery .ajax()?

So I've got a basic .ajax() POST method to a PHP file.

What security measures do I need?

A few posts around were mentioning using a hidden MD5 input field that you send via AJAX and verify in the PHP file. Is this a good enough method?

like image 287
Nathan Waters Avatar asked Feb 01 '12 02:02

Nathan Waters


People also ask

Is CSRF token necessary?

CSRF tokens prevent CSRF because without token, attacker cannot create a valid requests to the backend server. CSRF tokens should not be transmitted using cookies. The CSRF token can be added through hidden fields, headers, and can be used with forms, and AJAX calls.

Is CSRF token necessary with JWT?

If you put your JWTs in a header, you don't need to worry about CSRF. You do need to worry about XSS, however. If someone can abuse XSS to steal your JWT, this person is able to impersonate you.

When should a CSRF token be generated?

A CSRF Token is a secret, unique and unpredictable value a server-side application generates in order to protect CSRF vulnerable resources. The tokens are generated and submitted by the server-side application in a subsequent HTTP request made by the client.

Can we bypass CSRF token?

You can remove the CSRF token from the checking parameter and forward the request. I have seen many applications have a CSRF token enabled but they do not validate if the parameter is actually filled with the CSRF token.


2 Answers

The risk from CSRF is that an external site could send data to yours and the users browser will automatically send the authentication cookie along with it.

What you need is some way for the receiving action (that your $.ajax() method is sending POST data to) to be able to check that the request has come from another page on your site, rather than an external site.

There are a couple of ways to do this, but the recommended way is to add a token to the request that you can check for and that the hackers can't get to.

At its simplest:

  • On log on create a long random string token and save it against the user.
  • Add a parameter to the $.ajax() request that includes the token.
  • On request check that the token matches the one that you have saved for the user.
  • If the token doesn't match you have a CSRF hack.

The hacker can't get to your DB and can't actually read the page you've sent to the user (unless they get an XSS attack in, but that's another problem) so can't spoof the token.

All that matters with the token is that you can predict (and validate) it and that the hacker can't.

For this reason it's easiest to generate something long and random and store it in the DB, but you could build up something encrypted instead. I wouldn't just MD5 the username though - if the CSRF attackers figure out how to generate your tokens you'll be hacked.

Another way is to store the token is in a cookie (rather than your database), as the attackers can't read or change your cookies, just cause them to be re-sent. Then you're the token in the HTTP POST data matches token in the cookie.

You can make these a lot more sophisticated, for instance a token that changes every time it's successfully used (preventing resubmission) or a token specific to the user and action, but that's the basic pattern.

like image 51
Keith Avatar answered Sep 21 '22 19:09

Keith


In terms of request forgery, it doesn't matter how the client sends the request it matters how its received. The same CSRF rules apply for an ajax post as any other type of post.

I recommend reading the CSRF prevention cheat sheet. Using a per-user secret token is the most common form of protection.

like image 41
rook Avatar answered Sep 22 '22 19:09

rook