Welcome Guest, Not a member yet? Register   Sign In
Regenerate CSRF token and AJAX
#1

(This post was last modified: 07-18-2016, 04:31 AM by pb.sajjad.)

Hi to all...

I enable CSRF in my app with ajax calling. I know how to handle CSRF protection while using ajax. But in part of my app, there is a cascading select elements (one for state and one cities that via ajax, populate relate cities to selected state). If I set csrf_regenerate to True, there is an 403 (Forbidden) error, and when set it to FALSE, everything is ok.

My question is: How could I handle this issue, while $config['csrf_regenerate'] = TRUE.

CI Security Document:
Quote:The default regeneration of tokens provides stricter security.

Now is there any way? Or must be set this property to FALSE?

thanks.
Reply
#2

(This post was last modified: 07-18-2016, 07:12 AM by PaulD.)

If your AJAX uses a get instead of a post you will not have the issue as CSRF only works on post data. It sounds like you should be using a get anyway.

Alternatively, you need to get your new token and hash and return it in your ajax call, then update the token and hash settings in your html or your js.

Alternatively, you can make that particular url free from csrf using the config element $config['csrf_exclude_uris'] = array();

Best wishes,

Paul.
Reply
#3

(07-18-2016, 07:12 AM)PaulD Wrote: If your AJAX uses a get instead of a post you will not have the issue as CSRF only works on post data. It sounds like you should be using a get anyway.

Alternatively, you need to get your new token and hash and return it in your ajax call, then update the token and hash settings in your html or your js.

Alternatively, you can make that particular url free from csrf using the config element $config['csrf_exclude_uris'] = array();

Best wishes,

Paul.

I use POST.

Quote:Alternatively, you need to get your new token and hash and return it in your ajax call, then update the token and hash settings in your html or your js.

I get csrf token name and hash and put them in data for ajax calling like this:

Code:
$.ajax({
    type: "POST",
    url: post_url,
    data: {"<?= $this->security->get_csrf_token_name(); ?>" : "<?= $this->security->get_csrf_hash(); ?>"},
    //some more
    success: function(fields){
       //do operation
       }
});


When I change option in first select element, then I get that error. So how should I handling this? You said update token, how? In this way, shouldn't it update?

Quote:Alternatively, you can make that particular url free from csrf using the config element $config['csrf_exclude_uris'] = array();

For the last solution, I use it.
Reply
#4

(This post was last modified: 07-18-2016, 09:27 AM by arma7x.)

On sailjs for heavy websocket request is send a GET request via ajax to the built-in /csrfToken route, where it will be returned as JSON, e.g.:

{
"_csrf": "ajg4JD(JGdajhLJALHDa"
}
Keep calm.
Reply
#5

(This post was last modified: 07-18-2016, 11:28 AM by PaulD.)

This is how you first get your token name and hash, true

PHP Code:
$.ajax({
    
type"POST",
    
urlpost_url,
    
data: {"<?= $this->security->get_csrf_token_name(); ?>" "<?= $this->security->get_csrf_hash(); ?>"},
    
//some more
    
success: function(fields){
       
//do operation
       
}
}); 

But once you post, the hash changes, so now your hardcoded one in your js is no longer valid, hence your error.

What you have to do is get the new hash, and change either your js or a reference to the hash.

In the past I have done this in different ways. You could have a field such as <input type="hidden" name="hash" value=""> that you fill the value with the hash value when you first load the page. On subsequent js posts, finish with a js function call to something like refresh_token. That function would get the current hash and refill the value in the hidden field. Your js posts should query that field to get the hash in the first place, rather than being set in the js itself.

Another way is to have a js global value set to the hash value, and your refresh token call simply changes the global variable, that other js functions refer to.

Either way, whenever you post, you need to update the value of the hash your js functions refer to.

Hope that helps,

Paul.

PS I prefer to return the new hash in my js, because in that way I know the requesting ajax has a working/valid hash in the first place. So my js is more like:

Quote:function do_something()
{
// get hash from hidden field
// post something
// check return for success or fail
// if fail show error
// if success do whatever
// refresh hash in page with returned new hash value
}
Reply




Theme © iAndrew 2016 - Forum software by © MyBB