Kartik
Kartik

Reputation: 2609

How to set up XSRF protection in web apps?

I am a web application newbie. I know that XSRF protection questions have been asked in SO but the questions have been specific to a particular language (RoR/Python for example) or a library (jQuery). I would like to know how I can implement XSRF protection in my web application.

My understanding is that XSRF protection relies to using a unique random token that must be authenticated when a HTTP request is made. I have the following questions:

  1. When should the authentication token be initialized? Should it be set on page load (i.e. GET request)?
  2. Where should the token be initialized? Should they be set in input fields, cookies or request headers? How is this random value generated? How do I persist this value in order to be used for comparison?
  3. When should the authentication token be verified? How does I compare authentication tokens? How do I compare these tokens with the token that I have persisted?

Is there a difference in the set up for a synchronous form request versus an AJAX request?

Upvotes: 0

Views: 165

Answers (2)

Khanh TO
Khanh TO

Reputation: 48972

I'm not going to talk about a specific solution that you must follow as there are many, I'll talk about the main idea instead and you could implement it however you want.

The key idea to prevent XSRF is to store a random token in a place where code from other domains cannot access (such as a cookie). You could generate this token on server side and instruct the browser to store it locally for the entire session. (don't need to persist anything on server side)

Whenever you perform a request, send:

  • the token in your storage (if you use cookie, the browser will send it automatically).
  • the same token as the stored one in your request (whether as a header or in body using hidden field depending on how server code gets it)

On server side, the server will check for a match.

A sample code in jquery (with jquery cookie plugin):

$.ajax({
   url:"someurl",
   data:{token:$.cookie('token')}
});

The ability to read the cookie proves that this is from your domain, not external domains There are various ways to implement this mechanism (don't need to stick to a specific solution) as long as they stick the the main idea:

  • Storing a secret token on browser in a place code from other domains cannot read it.
  • Send the secret token and the same token from browser to your server. The ability to send that same token proves that this is not a XSRF request.

How do I persist this value in order to be used for comparison?

We could store it as a cookie or as a session variable. Personally, I prefer cookie because:

  • Reduce memory consumption on server side.
  • We don't need to include that token in every generated HTML file in order for the browser to send it back.

Is there a difference in the set up for a synchronous form request versus an AJAX request?

No, as long as you could prove this is not a XSRF request by sending the same token in the request. It does not matter where token is (a hidden field, a custom header,..). In case of Form, people usually send it as a hidden field.

Upvotes: 0

Quentin
Quentin

Reputation: 943214

When should the authentication token be initialized?

The first time, during a session, that the user arrives at a page containing any form that you wish to protect from CSRF attacks.

Should it be set on page load (i.e. GET request)?

It should be embedded in the form when the HTML for it is generated.

Should they be set in input fields, cookies or request headers?

Hidden inputs.

Using a cookie would miss the point (which is that it comes from the page and does not persist in the browser). Extra headers can only work when using XHR, use a general approach.

How is this random value generated?

With a random number generator

How do I persist this value in order to be used for comparison?

Sessions

When should the authentication token be verified?

As part of the authorization step.

How does I compare authentication tokens? How do I compare these tokens with the token that I have persisted?

if ( $request->paramaters->{csrf} eq $session->data->{csrf} )

Is there a difference in the set up for a synchronous form request versus an AJAX request?

No. You still have a session and you still have a piece of the POST data being the token.

Upvotes: 1

Related Questions