InvalidAuthenticityToken errors in mobile
Asked Answered
F

1

5

I have read multiple questions and answers here on StackOverflow about InvalidAuthenticityToken and protect_from_forgery but get none the wiser.

I have a website that get hundreds of these errors every day. They seem to be mainly (only?) from mobile but I have only verified that through samples.

I understand why there is an AuthenticityToken and the need for adding

<%= csrf_meta_tags %>

in the application.html (which I have) as well as having protect_from_forgery in the application controller. I have both the csrf_meta_tags and:

protect_from_forgery with: :exception

in my Application controller, as is default.

I realize I can "solve" the problem by removing protect_from_forgery but that would make me vulnerable for CSRF-attacks so that is not really a solution, is it? I could add an "except" for protect_from_forgery for the form posts that take place but that would leave me just as vulnerable, right?

Edit: I tried accessing the form with my mobile with cookies disabled and experienced a 422 error. Couldn't get it to cause the exception though. Adding an exception for my "result" function removed that, but that makes it vulnerable I guess?

Edit2: I have several forms on the same page (e.g. a search form). Perhaps this could affect the issue?

I am now in a position where I can't have it since it causes error for hundreds of users per day and I can't remove it because I am afraid that it will make my website vulnerable for hacks.

So, what can I do? Is there a decent middle ground?

Is there any way I can alter the protect_from_forgery and still feel fairly confident that I will not have my database destroyed by hackers?

I am not using any API for the site and all of the errors come from the same type of form. I understand there is a javascript part to this problem but not really how I can use that information to solve the problem.

Thanks in advance!

Example of exception that I get:

An ActionController::InvalidAuthenticityToken occurred in calculations#result: 

ActionController::InvalidAuthenticityToken 

------------------------------- 
Request: 
------------------------------- 

* URL : http://www.example.com/calculation/result 
* HTTP Method: PUT 
* IP address : 217.214.148.251 
* Parameters : {"utf8"=>"✓", "_method"=>"put", "authenticity_token"=>"udnClerrF5UWvg84uaD82TzmPx/vWssv2wN9UPqyn10UwXqbOwa2FBtnZ5Nfo7HPh9xbA2OSrrUNineW50XiYg==", "commit"=>"Calculate", "controller"=>"calculations", "action"=>"result", "id"=>"123"} 
* Timestamp : 2016-08-19 12:11:09 UTC 
* Server : 2696e83c-1538-434d-ab6d-4e16577698d0 
* Rails root : /app 
* Process: 6 

------------------------------- 
Session: 
------------------------------- 

* session id: "42b36aacc78102605cb3365922a550b1" 
* data: {"session_id"=>"42b36aacc78102605cb3365922a550b1", 
"_csrf_token"=>"KU43tmmXbxxgoabHrbejg+NWWP1tUVoWABNDqO8FiFI="} 


------------------------------- 
Environment: 
------------------------------- 

* CONTENT_LENGTH : 322 
* CONTENT_TYPE : application/x-www-form-urlencoded 
* HTTP_ACCEPT : text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
* HTTP_ACCEPT_ENCODING : gzip, deflate 
* HTTP_ACCEPT_LANGUAGE : sv-se 
* HTTP_CONNECTION : close 
* HTTP_CONNECT_TIME : 0 
* HTTP_COOKIE : __unam=91429fa-156a1632125-9bccf3-3; _ga=GA1.2.357545074.1471586444; _gat=1 
* HTTP_HOST : www.example.com 
* HTTP_ORIGIN : http://www.example.com
* HTTP_REFERER : http://www.kalkyleramera.se/calculation
* HTTP_TOTAL_ROUTE_TIME : 0 
* HTTP_USER_AGENT : Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_3 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G34 Safari/601.1 
* HTTP_VERSION : HTTP/1.1 
* HTTP_VIA : 1.1 vegur 
* HTTP_X_FORWARDED_FOR : 217.214.148.251 
* HTTP_X_FORWARDED_PORT : 80 
* HTTP_X_FORWARDED_PROTO : http 
* HTTP_X_REQUEST_ID : 5e925192-d6ea-4cd3-b049-20010f11f2c2 
* HTTP_X_REQUEST_START : 1471608669086 
Face answered 20/8, 2016 at 14:56 Comment(0)
A
2

This issue is discussed here. If it is your issue, you should see Can't verify CSRF token authenticity Completed 422 Unprocessable Entity within your logs. Two solutions are discussed

  • change cache control config.action_dispatch.default_headers.merge!('Cache-Control' => 'no-store, no-cache')
  • change invalid session to a null session protect_from_forgery with: :null_session

But it seems to be still an open issue.

Autotomize answered 20/8, 2016 at 15:47 Comment(6)
Thanks, I managed to create the issue on my dev-version through the help of that article. Also using protect_from_forgery with: :null_session "solves" the issue, just like adding an exception to that particular controller does...but my big question here: Is it safe to do so?Face
Also, just having "protect_from_forgery" makes the site at least not crash. So, I guess it is just a matter of what is the best option of these solutions?Face
with: :null_session is the default for Rails 5 and 4.2. For older versions I don't know. I would asume that it is save. It provides an empty session hash in the case of an issue with the csrf token. Changing Cache-Control may have performance impacts.Autotomize
I have to add a remark. You have to ensure that an empty session is not an issue for your app. For instance redirect in case nobody is logged in.Autotomize
I don't use logins for this site other than an admin. When could this be a problem? I can't really find much clear information when I google.Face
With null session or reset session the request is still processed even when csrf check fails. With a login system or a permission check in place this is mostly not an issue because the user is logged out without a valid session. Without a permission check I see no reason for a request forgery because every one can execute the action. What can happen is that you expect a certain session variable to be set but it isn't because of null session.Autotomize

© 2022 - 2024 — McMap. All rights reserved.