The attack works by including a link or script in a page that accesses a site to which the user is known to have authenticated. Then a task is performed as the logged in user.
Huh?
I could create an image tag
<img src="http://target_site/account/transfer?1milliondollars&from.you.to.me>
or I could put it in a hidden iframe (*holds pinkie up to corner of mouth)
Because you have a valid cookie for the target site this will work. By using post requests for something like this makes it harder to do but still possible. You should be using post when changing the state of a resource anyway.
What can I do?
From rails 2.0 we have a protect_from_forgery and a secret key. Rails helpers puts this key in every form request. This verifies that the request is coming from somebody using the page. It will protect all POST, PUT, DELETE requests.
If you’re using good ‘ol jQuery you’ll have to set this up yourself.
application_helper.rb
def yield_authenticity_token if protect_against_forgery? "<script type='text/javascript'> //<![CDATA[ window._auth_token_name = '#{request_forgery_protection_token}'; window._auth_token = '#{form_authenticity_token}'; //]]> </script>" end end
View
<%= yield_authenticity_token %>
application.js
$(document).ready(function() { // All non-GET requests will add the authenticity token // if not already present in the data packet $("body").bind("ajaxSend", function(elm, xhr, s) { if (s.type == "GET") return; if (s.data && s.data.match(new RegExp("\\b" + window._auth_token_name + "="))) return; if (s.data) { s.data = s.data + "&"; } else { s.data = ""; // if there was no data, jQuery didn't set the content-type xhr.setRequestHeader("Content-Type", s.contentType); } s.data = s.data + encodeURIComponent(window._auth_token_name) + "=" + encodeURIComponent(window._auth_token); });
Thank you Lawrence Pit for this code.


{ 0 comments… add one now }