• 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Ajax Question

#1
On my upload ajax I use Formdata but I would like to know how can I add / append the CSRF to it?

Code:
<?php echo $this->security->get_csrf_token_name(); ?>' : '<?php echo $this->security->get_csrf_hash(); ?>


Not sure where to put the secureity stuff on here

Code:
var formData = new FormData($(this).parent()[0]);
   formData.append('hash', $("#ask #input_hash").val());

Script

Code:
<script type="text/javascript">
$('#button-upload').on('click', function() {
    $('#form-upload').remove();
    
    $('body').prepend('<form enctype="multipart/form-data" id="form-upload" style="display: none;"><input type="file" name="file" /></form>');

    $('#form-upload input[name=\'file\']').trigger('click');
    
    $('#form-upload input[name=\'file\']').on('change', function() {
        var formData = new FormData($(this).parent()[0]);
           formData.append('hash', $("#ask #input_hash").val());

        $.ajax({
            url: "<?php echo base_url('questions/ask/upload');?>",
            type: 'post',        
            dataType: 'json',
            data: formData,
            cache: false,
            contentType: false,
            processData: false,        

            success: function(json) {
                if (json['success'])
                {
                    //alert('yes');
                }
            },
        });
    });
});    
</script>
There's only one rule - please don't tell anyone to go and read the manual.  Sometimes the manual just SUCKS!
Reply

#2
Hi,

What I do is to load the csrf security token into the body of the page somewhere, say in a div like this:

PHP Code:
<div id="security" data-token="<?php echo $security_token; ?>"></div

This div is set in the css with "display: none;" Then my js reads the token from this div. After it has finished, the results I return contain a new token, which I use to replace the original token on the page in this div.

Now when one ajax action is called after another ajax action, it too reads the token and gets a current one, not the old one.

I must admit that in the past I have also taken a short cut to not refresh the token, but I know this is a short cut and probably not the best for security. In the past I have also just disabled CSRF for a controller which is even worse really. I don't advise doing either of those two things.

I used to put the token name in the div too, but now I just hard code into the js whatever the name is, as it never changes once set anyway.

What I like about this is that my js can be in js files, not loaded into the controller and appended to the page. I have never liked doing that. Also, I can have many forms, many ajax functions and they all read the same token.

I often put the reading of the token and updating the token as a separate function so I am not having to rewrite the same code all the time, and this whole process is just two lines of js in the original functions.

Hope that helps,

Paul.

PS This is just the way I do it. I am no security expert but am quite happy with how this works for me. However should I need to change how I do this, at least I would only have to update the two common functions for reading and writing the tokens.

PPS On my pages, I do not allow two separate ajax actions to be happening at the same time, so if you submit a form to update a list title, while is loading (which is always very quick) I disable all the other click functions until it is complete, when they are all turned back on again. The speed at which it all works is usually so quick that you barely see the little loading spinner anyway, let alone have any user issues. But if a process stalls, the user is not clicking other forms elsewhere at any time causing a possible CSRF error.
Reply

#3
(07-01-2017, 05:29 AM)PaulD Wrote: Hi,

What I do is to load the csrf security token into the body of the page somewhere, say in a div like this:

PHP Code:
<div id="security" data-token="<?php echo $security_token; ?>"></div

This div is set in the css with "display: none;" Then my js reads the token from this div. After it has finished, the results I return contain a new token, which I use to replace the original token on the page in this div.

Now when one ajax action is called after another ajax action, it too reads the token and gets a current one, not the old one.

I must admit that in the past I have also taken a short cut to not refresh the token, but I know this is a short cut and probably not the best for security. In the past I have also just disabled CSRF for a controller which is even worse really. I don't advise doing either of those two things.

I used to put the token name in the div too, but now I just hard code into the js whatever the name is, as it never changes once set anyway.

What I like about this is that my js can be in js files, not loaded into the controller and appended to the page. I have never liked doing that. Also, I can have many forms, many ajax functions and they all read the same token.

I often put the reading of the token and updating the token as a separate function so I am not having to rewrite the same code all the time, and this whole process is just two lines of js in the original functions.

Hope that helps,

Paul.

PS This is just the way I do it. I am no security expert but am quite happy with how this works for me. However should I need to change how I do this, at least I would only have to update the two common functions for reading and writing the tokens.

PPS On my pages, I do not allow two separate ajax actions to be happening at the same time, so if you submit a form to update a list title, while is loading (which is always very quick) I disable all the other click functions until it is complete, when they are all turned back on again. The speed at which it all works is usually so quick that you barely see the little loading spinner anyway, let alone have any user issues. But if a process stalls, the user is not clicking other forms elsewhere at any time causing a possible CSRF error.

Update I think I have now got it working doing this way lets me submit now. The form open generates CSRF token it automatic.

Code:
var formData = new FormData($(this).parent()[0]);
    formData.append('hash', $("#ask #input_hash").val());
    formData.append('<?php echo $this->security->get_csrf_token_name(); ?>', $('#ask input[name="<?php echo $this->security->get_csrf_token_name(); ?>"]').val());
There's only one rule - please don't tell anyone to go and read the manual.  Sometimes the manual just SUCKS!
Reply

#4
If you are regenerating the token on each request, and your ajax empties the form for the next submit if successful (such as on a task list, adding a task) on the second submit the form might have a csrf error as the token is now out of date. If it is a single use form, then the way you have done it is fine.

Also this will only work if you js is inline, not in a js file. As I mentioned, I like to keep my js in files not inline, but there is no right or wrong way.

Best wishes,

Paul.
Reply


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


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