Strange behavior

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

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 ?

  • in urls means space - if the token genuinely contains + then you need to escape it before putting it in the URL.

Fred

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