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?
A CSRF attack works because browser requests automatically include all cookies including session cookies. Therefore, if the user is authenticated to the site, the site cannot distinguish between legitimate authorized requests and forged authenticated requests.
To prevent a CSRF attack, developers can verify the presence of custom headers and values across the AJAX endpoints on the server-side. This approach does not usually require introducing server-side state data or making UI changes.
Since AJAX calls are encrypted with a session key, AJAX queries cannot be sent directly to the server. If an attempt is made to send queries directly, the response given by the page will be "Forbidden," as the page expects to receive encrypted text in the AJAX call.
CSRF POST Request AttackGET requests are not the only way to trigger a CSRF attack. An attacker can forge a form. Walking through it step-by-step will help explain how such an attack is structured. Imagine that an attacker does some research to see what a legitimate bank looks like.
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 you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With