• 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Multple CSRF token?

#1
Hello CI community Smile I am pretty new to CI and using CI3 in my site Smile
I have a ajax based form that may send more than one post request to a controller method, but the problem is once a request sent then the CSRF token fails from the second request.
I am generating CSRF like this-
PHP Code:
$this->security->get_csrf_hash();
$this->security->get_csrf_token_name(); 
Now what to do? Or is there any CI way for ajax requests and responses?
Thanks
Reply

#2
you could simply disable csrf for that page in the config.php: http://www.codeigniter.com/userguide3/li...rgery-csrf

Also, take a look at CSRF regeneration.
Reply

#3
Hi rakibtg,

I recently ran into this dilemma and the solution that I went with is as follows:

- When the page loads, echo the first token into a hidden input in the form.
- On each ajax request (first & thereafter) send a new token in the response headers
- Store that token for use with the next request

I used $.ajaxSetup() to add the token to each AJAX call and the $.ajaxSuccess() to store the new token on each AJAX response. Here are some code samples to give you a better idea:

1. Ajax_Controller.php (receives ajax calls from browser)

PHP Code:
header('CI-CSRF-Token: '$this->input->security->get_csrf_hash()); // pass a new token back on each request 

2. ajax-helper.js (loaded on every page that uses ajax calls)
Code:
//Setup AJAX to use the first token from the hidden input - see footer.php
$(function($) {    
    $.ajaxSetup({
        data: {
            csrf_test_name : $('#csrf').val()
        }
    });
});

//Update CSRF token on any ajax request so we're all good for the next one
$(document).ajaxSuccess(function(event, jqXHR, settings) {    

    resetAjaxToken(jqXHR);

});

//Get the token from an AJAX response and re-setup AJAX to send the new token.
function resetAjaxToken(jqXHR) {

   var token = jqXHR.getResponseHeader("CI-CSRF-Token");

   $.ajaxSetup({
       data: {
           csrf_test_name : token
       }
   });
}

3. footer.php (Common footer for all pages, so all pages include an initial CSRF)

PHP Code:
<input type="hidden" id="csrf" name="<?= $csrf->name; ?>" value="<?= $csrf->hash; ?>" /> 

Obviously, this is only required if you're using CSRF regeneration but it sounds like you are. To me, this seems the most secure method and doesn't require you to disable CSRF etc.

Let me know if that make sense!

Dave
Reply

#4
Its a brilliant idea Smile Thanks Dave for sharing this, it really helps Smile
Reply

#5
If you're using CI3 set csrf_regenerate to false, echo the name/hash into an input and send it along with each request. Regenerating the token brings almost 0 security advantage and any concurrent requests will break if you have it set to true. If a user clicks the back button and tries to resubmit a form it will break as well as the token will be stale.
Reply

#6
(03-01-2015, 10:52 AM)spjonez Wrote: If you're using CI3 set csrf_regenerate to false, echo the name/hash into an input and send it along with each request. Regenerating the token brings almost 0 security advantage and any concurrent requests will break if you have it set to true. If a user clicks the back button and tries to resubmit a form it will break as well as the token will be stale.

Its a great idea! Thank You so much for sharing...
Reply

#7
(03-01-2015, 10:52 AM)spjonez Wrote: If you're using CI3 set csrf_regenerate to false, echo the name/hash into an input and send it along with each request. Regenerating the token brings almost 0 security advantage and any concurrent requests will break if you have it set to true. If a user clicks the back button and tries to resubmit a form it will break as well as the token will be stale.

woow this is awesome for me Smile but i this way what about security? if i set it to TRUE, how my much be secure?
ressan.ir
CI is nice Heart
Reply


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


  Theme © 2014 iAndrew  
Powered By MyBB, © 2002-2021 MyBB Group.