简体   繁体   中英

protecting against CSRF on ajax requests and forms without submit buttons

I'm fairly new to web security. I was wondering what would be the correct way to use tokens on ajax requests and forms without submit buttons (ie status updates) to protect agains CSRF. Could someone show me a code sample? I know how to do it properly for forms with a submit button. Also in my ajax folder I have a htaccess with the following:

SetEnvIfNoCase X-Requested-With XMLHttpRequest ajax
Order Deny,Allow
Deny from all
Allow from env=ajax

Is that enough security for ajax requests, or should i also implement token security for ajax requests?

All you need to do is generate a secret (token) when the page loads. Place it on the page, and in session. Typically I put it in the form as a hidden field if I can, or if it is part of a larger very ajaxy page, I'll put it in a value attribute on a related element like the div wrapping the whole page. Others will add a script tag with a variable set to the secret.

Then, whenever you make an AJAX call or send the form, you include a field for the secret. (Cheekysoft's answer goes into more detail about how to do this with raw JS, it can be done roughly the same with jQuery or any other framework you might be using.) Match it to the session value on the back end to ensure they are still the same (came from the same source), and you are good.

If you want added security, regenerate the secret on each request and return that new secret along with the requested data. Have all your ajax requests replace that hidden field or value attribute with the new value. This doesn't really work well if you are performing lots of requests, or concurrent requests. Really, generating one each time the whole page is loaded should be enough if you are doing this over HTTPS, which you should be.

If you aren't doing this over HTTPS, then it really doesn't matter, someone sitting in an internet cafe / starbucks can just steal the session and reload the page.

If you are going to be doing this a lot, it is worth checking out jQuery and various plugins that will help do the CSRF protection for you. Also, my way isn't the only way.

If your XHR is a GET request, include the token as a URL parameter and have the PHP script read it from $_GET[] . If your XHR is a POST, pop the token into the POST data and have the PHP script read it from $_POST[] .

GET request

var token = getElementById( 'myHiddenField' ).value;
var xhr = new XMLHttpRequest();
xhr.open( 'GET', 'server.php?token=' + token );
xhr.send( null );

POST request

var token = getElementById( 'myHiddenField' ).value;
var xhr = new XMLHttpRequest();
xhr.open( 'POST', 'server.php', true );
xhr.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' );
xhr.onreadystatechange = function() {
  if (xhreq.readystate != 4) { return; }
  // do client side stuff here
};
xhr.send( 'token=' + token );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM