In the process of updating Webiva to the newest version of Rails, on the obstacles we had to overcome was adding in support for CSRF protection throughout the system. This is an essential protection for any system but an absolute must for a system like an open-source CMS where anyone can study the code and make an educated guess about what users and content to attack (user id #1 for example)
Working with standard forms in Webiva code base proved to be not that difficult as the form_tag function automatically attaches the required CSRF token, however dealing with hand-coded Ajax calls in the prototype library and seemed like it was going to be a major pain, with the worst case scenario being manually attaching a authenticity_token= parameter to each request (there were probably a couple hundred of them). Luckily there was an easy workaround. We ended up just adding the following code to the top of each layout:
<script> var AUTH_TOKEN = "<%= form_authenticity_token.to_s %>";</script>
And then just added the following to the bottom of application.js:
try { if (!AUTH_TOKEN) AUTH_TOKEN = 'DummyToken'; }
catch (e) { AUTH_TOKEN = 'DummyToken'; }
Object.toQueryString = function (object) {
var result = $H(object).toQueryString();
if (!result.include ("authenticity_token"))
{
result += "&authenticity_token=" + encodeURIComponent (AUTH_TOKEN);
}
return result;
};
Since Prototype calls Object.toQueryString on any parameters passed to Ajax.Request or Ajax.Update the authenticity token should be added in automatically. For testing purposes I added in the try / catch block just to make sure something is set so that if AUTH_TOKEN isn't set we get a server error that can be tracked more easily than just a javascript error on the client side.
....and follow @cykod on twitter
Comments Leave a comment
I’ve wrote rails plugin that adds authenticity_token to all non GET Ajax requests. You can check it out on http://github.com/vlado/remote_forgery_protection or http://kolodvor.net/2010/01/02/rails-csrf-and-ajax-requests
Leave a Comment