Search code examples
ajaxsecuritycodeignitercsrf

Pass Codeigniter CSRF string to server via AJAX


I have enabled Codeigniter's CSRF protection on my site that uses AJAX to submit a user form and handles some other user interaction which require data submission via AJAX. As a result I came up against the "action not allowed" server side error. I quickly worked out that only the data my javascript collected and submitted via AJAX was passed to the server and as a result the CSRF code was not being sent.

The generated token tag looks like:

<input type="hidden" name="csrf_test_name" value="dsflkabsdf888ads888XXXXXX" />

So it seems to me the simplest way to submit the token to the server for verification is using a jQuery selector on csrf_test_name to get the value and then adding this to my post data for the server to verify. As per the code below:

//get CSRF token
var csrf = $('[name="csrf_test_name"]').val();

//build the form data array
var form_data = {
    csrf_test_name: csrf,
     ... ... ...
     ... ... ...
}

//send the form data to the server so it can be stored
$.ajax({
    type: "POST",
    data: form_data,
    url: ...,
    dataType: "html",
    success: function(msg){
         ... ... ...
    }//end success
});//end ajax

I have followed this procedure for every ajax submission that sends data to the server and the server side error is fixed and everything works fine.

To test this I have hard coded in an incorrect CSRF token and the server detects the inconsistency and returns an erro code 500 so on the surface this works.

My question is this, is this a safe way to do this and is there an expected best practice to follow? I have done some google searching on this and it seems all the other methods are more complex and I am wondering if my way creates an attack vector that I can't see/workout.


Solution

  • an easier method is to pass that csrf to $.ajaxSetup() that way it's included with any $.ajax() request afterward.

    var csrf = $('input[name="csrf_test_name"]').val();
    var data = {};
    data[CSRF] = csrf;
    
    $.ajaxSetup({ 'data': data });
    

    then no need to include data: { csrf_test_name: 'xxx', ... } in requests after setup.