Welcome Guest, Not a member yet? Register   Sign In
Disallowed Key Characters
#1

[eluser]vincej[/eluser]
Hi - I am trying to get CSRF to work with an AJAX call. I have researched various forums and methods and everything fails. The only one which gives some promise is this one I found on StackOverflow:

http://stackoverflow.com/questions/73483...rf-problem


The orginal poster added the csrf tokens as a var which does not work for me as I am not using JQuery:

Code:
var post_data = {
        'ansid': valrad,
        '<?php echo $this->security->get_csrf_token_name(); ?>' : '<?php echo $this->security->get_csrf_hash(); ?>'
    };


I am using a Scriptaculous script which needs it added as a parameter. I am no longer gettng the "This Action is Not Allowed" , which is great, but instead I now get "Disallowed Key Characters. Ok, I have tried modifying the allowable key characters inside the core/input.php, but unless I am reading it wrong ":" is allowed. So again I am stumped.

I had to concatenate the ":" to avoid a js error, as seen below.


Code:
var params = 'ids='+parameter_string +'<?php echo $this->security->get_csrf_clftoken(); ?>' +':'+ '<?php echo $this->security->get_csrf_hash(); ?>'  

  var ajax = new Ajax.Updater(
    'ajax_msg','http://localhost/mysite/index.php/welcome/ajax_cart', {method:'post',parameters:params,onComplete:showMessage}
    );


This whole csrf thing in CI is completely killing me.

Any ideas why I am now getting disallowed key characters ??

many thanks !!

#2

[eluser]www.sblog.in[/eluser]
You can do like below

You have a form with hidden input field which holds csrf token value

Code:
<form id="form" name="form" acti method="post">
<?php echo form_hidden($this->security->get_csrf_token_name(), $this->security->get_csrf_hash()); ?>
<input type="text" name="string" />
</form>

Then in ajax you can call

Code:
var cct = $("input[name=csrf_token_name]").val();
var token = $('#form').serialize();
var url = 'http://localhost/mysite/index.php/welcome/ajax_cart';
var data = 'ids='+string,
$.ajax({
                type: "POST",
                //async: false,
                url: url,
                data: data,
                dataType: "html",
                cache: false,
                csrf_token_name: cct,
                success: function(resp) {
                    alert(resp);
                }
            });
#3

[eluser]CroNiX[/eluser]
Scriptaculous? Didn't know that was even still around, which is probably why no one is helping you specifically with it since it's not very common. Personally, I'd avoid it, as it doesn't even seem to be updated in the last FOUR years (https://github.com/madrobby/scriptaculous)

I see no docs for "Ajax.Updater" on the scriptaculous site http://madrobby.github.io/scriptaculous/ so can't really help there. Do you have a link to the docs for that?

What is the value (output) of params after you create it? Is it valid json? Is it a parameterized query string? What does the scriptaculous script expect? It looks like you are using both ways (since you are using = along with : ), which can't be right. log params to the js console and show the output.

You are also missing a semicolon after the params declaration.
#4

[eluser]vincej[/eluser]
You're right. I added this script years ago and never changed it. It worked, so why bother. Now I am starting to realize that it may be time to change it, but I am nervous about doing that as, it works .. well kind of.

In fact the Ajax.Updater is part of Prototype which of course is part of Scriptaculous.

http://api.prototypejs.org/ajax/Ajax/Updater/


This morning I have tried a new approach, where I pass the csrf_token_name : csrf_token value into the params. This is rejected as well. Google Chrome reports the scope variables as:

Code:
<return>: undefined
ajax: Object
cct: "c037bc424fcca019c7956208b13f4e92"
csrf: "csrf_clftoken"
parameter_string: "4061:1,"
params: "ids=4061:1,csrf_clftoken:c037bc424fcca019c7956208b13f4e92"
real_id: "4061"
real_value: "1"
temp: Array[3]
tempid: "li_id_4061"
this: Window


The script which creates this is:

Code:
function jsUpdateCart(){
  var cct = document.getElementsByName("csrf_clftoken")[0].value;
  var parameter_string = '';
  allNodes = document.getElementsByClassName("process");
  for(i = 0; i < allNodes.length; i++) {
   var tempid = allNodes[i].id;
    var temp = new Array;
    temp = tempid.split("_");
  var real_id = temp[2];
  var real_value = allNodes[i].value;
var csrf = 'csrf_clftoken';
    parameter_string += real_id +':'+real_value+',';  
  }
  var params = 'ids='+parameter_string+csrf+':'+cct;
  var ajax = new Ajax.Updater(
    'ajax_msg','http://localhost/mysite/index.php/welcome/ajax_cart', {method:'post',parameters:params,onComplete:showMessage}
    );

}


Maybe it would be easier if I throw in the towel and convert to JQuery Ajax. I am thinking that in fact the only thing that would need changing would be the Ajax.Updater piece and I could keep the For loop - Correct ??


Thanks for all your trouble - I am terrible at Javascript.


cheers !
#5

[eluser]CroNiX[/eluser]
The problem looks like the way you are creating "params". It looks like it needs to be a json object, but you are mixing json notation with query string notation.

params should be something like {key:"value", key:"value", key:"value"}, but yours is ids=4061:1,csrf_clftoken:c037bc424fcca019c7956208b13f4e92"
#6

[eluser]CroNiX[/eluser]
Hard to decipher everything you have there as some of it seems overly complex, and without seeing the form side of things, but try this:
Code:
function jsUpdateCart() {
    var params = {}; //create new object
    params['csrf_clftoken'] = document.getElementsByName("csrf_clftoken")[0].value; //add the csrf key:value

    //cycle through and add all other key:value pairs
    var allNodes = document.getElementsByClassName("process");
    for(i = 0; i < allNodes.length; i++) {
       var temp = allNodes[i].id.split('_');
       params[temp[2]] = allNodes[i].value;
    }

    var ajax = new Ajax.Updater(
'ajax_msg','http://localhost/mysite/index.php/welcome/ajax_cart', {method:'post',parameters:params,onComplete:showMessage}
    );
}
#7

[eluser]vincej[/eluser]
Thank you very much for this. Well I frigged around with it some more using your suggestion:

Code:
var token = {};
    token['csrf'] = document.getElementsByName("csrf_clftoken")[0].value;

The For Loop goes here, then later:


Code:
var params = 'ids='+parameter_string+token['csrf'];

  var ajax = new Ajax.Updater(
    'ajax_msg','http://localhost/mysite/index.php/welcome/ajax_cart', {method:'post',parameters:params,onComplete:showMessage}
    );

Unfortunately I still could not get it to work. Still the same "Action not allowed .... "

The variables came out looking much the same as yesterday according to Google Chrome:

Code:
<return>: undefined
ajax: Object
csrf: "csrf_clftoken"
parameter_string: "4061:1,"
params: "ids=4061:1,c741e91716543ca1dbfba5e1203cd576"
real_id: "4061"
real_value: "1"
temp: Array[3]
tempid: "li_id_4061"
this: Window
token: Object

I'm thinking that simply passing in the token value is not enough. Should I not have to pass in the token name in a key:value pair ??

I don't know what to do next - perhaps replace the Ajax.Update with JQuery Ajax ?? The for loop does not have to change.

Many Thanks !




Theme © iAndrew 2016 - Forum software by © MyBB