Guys,
I’m using some AJAX on my application, but when protect_from_forgery is on sometimes it works and sometimes the user session is killed. Today i found out why.
It happens the following:
The authenticity_token is sent correctly as you can see below,
Started DELETE “/clients/118/files/20?authenticity_token=hoMH9/heaFWXWWy+aE1xKQcpf4xrLoVWGqkq0pzzwuo=” for 127.0.0.1 at Wed Apr 27 23:06:50 -0300 2011
but, next line on server is,
Processing by ClippingsController#destroy as JS
Parameters: {“authenticity_token”=>“hoMH9/heaFWXWWy aE1xKQcpf4xrLoVWGqkq0pzzwuo=”, “id”=>“20,”, “client_id”=>“118”}
as you can see, the plus sign (‘+’) turned into a white space. Once the token doesn’t match the user session is killed.
Is someone experiencing this ? Any help how to fix it ?
Thanks,
Ernesto
How i escape it before the rails server process it ?
Thanks,
Ernesto
How i escape it before the rails server process it ?
You'll need to do that at the point that you add the token to the link
Fred
I did some brute force only to test, like this:
some characters are escaped, but now the link_to … :method => delete is not working anymore (the user session is killed).
If I user URI.escape the plus sign is not escaped.
So, i’m still at point zero.
Thanks,
Ernesto
I did some brute force only to test, like this:
some characters are escaped, but now the link_to … :method => delete is not working anymore (the user session is killed).
If I user URI.escape the plus sign is not escaped.
How are you adding the authenticity token to the URL ? (Ps, rails has a csrf_meta_tag helper)
Fred
I’m using csrf_meta_tag and the the headers appears correctly. The problem is when the athenticity_token has a plus sign and I use any of Jquery ajax function. So I tried to render the
form_authenticity_token already escaped using that method above ( CGI.escape), but now the jquery ajax function works and this line isn’t working anymore(when i click):
<%= link_to “Destroy”, [@client, address], :confirm => ‘Are you sure?’, :method => :delete %>
After the click there ins’t user session anymore:
Started POST “/clients/97” for 127.0.0.1 at Sat Apr 30 21:49:15 -0300 2011
Processing by ClientsController#destroy as HTML
Parameters: {“authenticity_token”=>“MCVYdvbAS4i7BiRaDZig9VHXbxltKo84BgDT%2BTL28%2BI%3D”, “id”=>“97”}
When I use ajax is ok:
Started DELETE “/clients/118/files/9?authenticity_token=MCVYdvbAS4i7BiRaDZig9VHXbxltKo84BgDT%2BTL28%2BI%3D” for 127.0.0.1 at Sat Apr 30 21:48:52 -0300 2011
Processing by ClippingsController#destroy as JS
Parameters: {“authenticity_token”=>“MCVYdvbAS4i7BiRaDZig9VHXbxltKo84BgDT+TL28+I=”, “id”=>“9,”, “client_id”=>“118”}
In both cases the csrf header is exactly the same and i’m using the CGI.escape method.
Any help ?
Thanks,
Ernesto
Sorry about this mess, but I just figured it out what was really happening and fixed it.
Rails probably always interpret the plus sign as a white space, but everything started because I couldn’t find how the authenticity_token is sent using <%= link_to “Destroy”, [@client, address], :confirm => ‘Are you sure?’, :method => :delete %>, initially I thought it was sent without any encoding. So I couldn’t say the difference between the request generated by the link_to method and my ajax request ( Started DELETE “/clients/118/files/20?authenticity_token=hoMH9/heaFWXWWy+aE1xKQcpf4xrLoVWGqkq0pzzwuo=” for 127.0.0.1 at Wed Apr 27 23:06:50 -0300 2011 ).
I think Rails under the hood encode the authenticity_token before sending it. So, now i’m doing it on javascript:
token_param = “authenticity_token=” + encodeURIComponent(token);
And this generates: “authenticity_token=hoMH9%2FheaFWXWWy%2BaE1xKQcpf4xrLoVWGqkq0pzzwuo%3D”
Then, it’s solved! Thanks for all the help!
Ernesto