Welcome Guest, Not a member yet? Register   Sign In
CodeIgniter CSRF Protection With Ajax
#1

Hi! CI Forum Members,

I am developing an application using CI. Most of My forms use Ajax to push data to the server. I am currently working on adding CSRF protection to all my forms.

I read this note from the documentation in CSRF section that:
Quote:Tokens may be either regenerated on every submission (default) or kept the same throughout the life of the CSRF cookie. The default regeneration of tokens provides stricter security,
and so, I choose to regenerate csrf_token.

Using Ajax, the page is not refreshed and thus resulting into the page having invalid token for further submissions which will always fail. 

I have decided to follow the advice from one of the website/blog to read csrf_token from the cookie using javascript cookie library, and pass it  along with every post request.

Here is code snippet:

PHP Code:
$("#selector").click(function () {
 
   e.preventDefault();
 
   var form_data = {
 
       cat_name: $('#something').val(),
 
       csrf_token_name: $.cookie("csrf_cookie_name")
 
   };

 
   $.ajax({
 
       type"POST",
 
       urlSITE_URL "controller",
 
       dataform_data,
 
       success: function(data) {
 
           alert('it worked');
 
       }
 
   });
}); 
 
Is this implementation safe to use for csrf protection? What are the risks if any?

Any help or recommendation is appreciated!
Reply
#2

If you're regenerating tokens what you posted won't work since you aren't updating the cookie's value after each request. If you want to use regenerate=true you'll need to save the current value in JS (I wouldn't use a cookie) and pass it through AJAX, then return the new CSRF token in the success callback to use for the next request.

That won't work if you send concurrent requests so your mileage may vary depending on how much AJAX you're using. Personally I would turn off regenerate, pass the same token each request  and put this in your htaccess.

Code:
# prevent app from being loaded in an iframe
Header always append X-Frame-Options SAMEORIGIN
Reply
#3

(09-15-2016, 05:52 AM)spjonez Wrote: If you're regenerating tokens what you posted won't work since you aren't updating the cookie's value after each request. If you want to use regenerate=true you'll need to save the current value in JS (I wouldn't use a cookie) and pass it through AJAX, then return the new CSRF token in the success callback to use for the next request.

That won't work if you send concurrent requests so your mileage may vary depending on how much AJAX you're using. Personally I would turn off regenerate, pass the same token each request  and put this in your htaccess.

Code:
# prevent app from being loaded in an iframe
Header always append X-Frame-Options SAMEORIGIN

But the cookie is read on-click event. That's for example, when the submit button is clicked, the cookie is read. So I assume that it will always contain current csrf_token that matches the one in the server.
Reply
#4

(This post was last modified: 09-15-2016, 06:31 AM by dave friend.)

If you choose to regenerate csrf_token you can pass the new CSRF value back to ajax easily enough. Your controller can get the newly created token (hash) with this.
Code:
$hash = $this->security->get_csrf_hash();

You can also get the token name
Code:
$name = $this->security->get_csrf_token_name();

Return those values in a way that is useable in the ajax success function.
Then use the "name" to find the input element and replace the value of that element with the "hash".

You're now good to go for another POST.
Reply
#5

(This post was last modified: 09-16-2016, 11:42 AM by spjonez.)

(09-15-2016, 06:05 AM)SammieL Wrote: But the cookie is read on-click event. That's for example, when the submit button is clicked, the cookie is read. So I assume that it will always contain current csrf_token that matches the one in the server.

Cookies are static data stored in your web browser and will not update unless you tell them to. If you are regenerating CSRF tokens per request your cookie will always have the first value you gave it and not the new value after each request.
Reply
#6

I've try it before. I get the new value from my controller then post it to my success and change the value of my hash. but nothings happen it sending me the error 403 forbidden access.
Reply




Theme © iAndrew 2016 - Forum software by © MyBB