{"action":"created","issue":{"url":"https://api.github.com/repos/rails/rails/issues/21948","labels_url":"https://api.github.com/repos/rails/rails/issues/21948/labels{/name}","comments_url":"https://api.github.com/repos/rails/rails/issues/21948/comments","events_url":"https://api.github.com/repos/rails/rails/issues/21948/events","html_url":"https://github.com/rails/rails/issues/21948","id":111136803,"number":21948,"title":"CSRF protection prevents some webkit users from submitting forms","user":{"login":"zetter","id":149785,"avatar_url":"https://avatars.githubusercontent.com/u/149785?v=3","gravatar_id":"","url":"https://api.github.com/users/zetter","html_url":"https://github.com/zetter","followers_url":"https://api.github.com/users/zetter/followers","following_url":"https://api.github.com/users/zetter/following{/other_user}","gists_url":"https://api.github.com/users/zetter/gists{/gist_id}","starred_url":"https://api.github.com/users/zetter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zetter/subscriptions","organizations_url":"https://api.github.com/users/zetter/orgs","repos_url":"https://api.github.com/users/zetter/repos","events_url":"https://api.github.com/users/zetter/events{/privacy}","received_events_url":"https://api.github.com/users/zetter/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":4,"created_at":"2015-10-13T09:00:15Z","updated_at":"2015-10-20T06:17:31Z","closed_at":null,"body":"Hi,\r\n\r\nWe've recently been investigating reports from our users that they are unable to submit forms.\r\n\r\nUpon investigation it appears that browsers can get in a state where Rail's CSRF (Cross-Site Request Forgery) protection stops the form being submitted.\r\n\r\n## To reproduce\r\n\r\nIt's possible to produce a minimal Rails app which has this problem:\r\n\r\n```bash\r\nrails new csrf-test\r\ncd csrf-test\r\nbundle exec rails generate scaffold Test test:string\r\nbundle exec rake db:migrate\r\nbundle exec rails server\r\n```\r\n\r\n#### How to replicate it on mobile Safari (tested on iOS9):\r\n+ Load a page containing a form (will be <http://localhost:3000/tests/new> in this example).\r\n+ Quit Safari by double-tap the home button and swipe up.\r\n+ Open Safari from the home screen. You should see the same page with the form.\r\n+ Submit the form.\r\n\r\nYou will see the Rails invalid authenticity token error- this is a \"The change you wanted was rejected\" message in production, or an `ActionController::InvalidAuthenticityToken` in development. I've also made [a video that follows theese steps](https://www.youtube.com/watch?v=bKDu0qMT4HM).\r\n\r\n#### How to replicate on Desktop Safari (tested on Safari 9.0 on OSX)\r\n+ Go to 'Safari' > 'Preferences...' > 'General' and set 'Safari opens with:' to 'All windows from last session'. \r\n+ Load a page containing a form (will be <http://localhost:3000/tests/new> in this example).\r\n+ Quit Safari (with CMD+Q)\r\n+ Open Safari. You should see the same page with the form.\r\n+ Submit the form.\r\n\r\nThis problem seems to happen regardless if:\r\n+ the app is served HTTP or HTTPS\r\n+ the app's environment is `development` or `production`\r\n+ the browser is manually quit by the user, or quit by the OS (to save memory)\r\n\r\nI have also been able to replicate on Chrome on Android. I haven't yet been able to replicate it on Chrome and Firefox on OSX using their 'restore tabs' options like I did in Safari. There may be other browsers that are affected.\r\n\r\n## What's happening\r\n\r\nLooking at the Rails logs, and the cookie submitted by the browser I believe that the browsers are caching the page, but clearing session cookies. This means the form has a `authenticity_token` parameter, but the Rails session cookie has been cleared so has no corresponding `_csrf_token`.\r\n\r\nHere is a annotated log showing this:\r\n```log\r\n# Browser loads the form for the first time\r\nStarted GET \"/tests/new\" for 127.0.0.1 at 2015-10-13 09:23:18 +0100\r\n  ActiveRecord::SchemaMigration Load (0.1ms)  SELECT \"schema_migrations\".* FROM \"schema_migrations\"\r\nProcessing by TestsController#new as HTML\r\n  Rendered tests/_form.html.erb (37.0ms)\r\n  Rendered tests/new.html.erb within layouts/application (41.4ms)\r\nCompleted 200 OK in 256ms (Views: 243.3ms | ActiveRecord: 0.3ms)\r\n\r\n# (Asset requests ommited)\r\n\r\n# Browser quits, clearing session cookies\r\n# Browser re-opens, reloads the page from cache without doing a request\r\n\r\n# Browser posts the form:\r\nStarted POST \"/tests\" for 127.0.0.1 at 2015-10-13 09:23:37 +0100\r\nProcessing by TestsController#create as HTML\r\n  Parameters: {\"utf8\"=>\"✓\", \"authenticity_token\"=>\"IhsNUyL6Y/riLIujH+ExkTZN9pEPfwAVVB/t9pwrnkIR6lw1bAl3ZFY+bPg+zqMf3pj3qeY0vgbKblrWgr0vnQ==\", \"test\"=>{\"test\"=>\"\"}, \"commit\"=>\"Create Test\"}\r\nCan't verify CSRF token authenticity\r\nCompleted 422 Unprocessable Entity in 1ms (ActiveRecord: 0.0ms)\r\n\r\nActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):\r\n  actionpack (4.2.4) lib/action_controller/metal/request_forgery_protection.rb:181:in `handle_unverified_request'\r\n  actionpack (4.2.4) lib/action_controller/metal/request_forgery_protection.rb:209:in `handle_unverified_request'\r\n  actionpack (4.2.4) lib/action_controller/metal/request_forgery_protection.rb:204:in `verify_authenticity_token'\r\n  # (Stack trace truncated)\r\n```\r\n\r\nI've tried to find more documentation about this kind of caching that browsers do. I found this article about the [WebKit Page Cache](https://www.webkit.org/blog/427/webkit-page-cache-i-the-basics/) but it appears to be out of date (it says HTTPS pages do not use the Page Cache, but I have seen this problem on HTTP and HTTPS pages). If anyone can find more about this I'd love to know.\r\n\r\nI'd like to know:\r\n+ Have others seen this problem? I haven't been able to find reported before, or find any documentation regarding this, but perhaps I have missed something.\r\n+ Is there a way that Rails could be changed that would prevent this happening?\r\n+ Are there any workarounds for this that we could apply in our application?\r\n\r\nThanks for any help."},"comment":{"url":"https://api.github.com/repos/rails/rails/issues/comments/149445699","html_url":"https://github.com/rails/rails/issues/21948#issuecomment-149445699","issue_url":"https://api.github.com/repos/rails/rails/issues/21948","id":149445699,"user":{"login":"alepore","id":557414,"avatar_url":"https://avatars.githubusercontent.com/u/557414?v=3","gravatar_id":"","url":"https://api.github.com/users/alepore","html_url":"https://github.com/alepore","followers_url":"https://api.github.com/users/alepore/followers","following_url":"https://api.github.com/users/alepore/following{/other_user}","gists_url":"https://api.github.com/users/alepore/gists{/gist_id}","starred_url":"https://api.github.com/users/alepore/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alepore/subscriptions","organizations_url":"https://api.github.com/users/alepore/orgs","repos_url":"https://api.github.com/users/alepore/repos","events_url":"https://api.github.com/users/alepore/events{/privacy}","received_events_url":"https://api.github.com/users/alepore/received_events","type":"User","site_admin":false},"created_at":"2015-10-20T06:17:31Z","updated_at":"2015-10-20T06:17:31Z","body":"interesting topic, i see this error quite often.\r\n@zetter here there's some mention about CSRF token in cookies, but it's used with javascript for caching purposes https://www.fastly.com/blog/Caching-the-Uncacheable-CSRF-security"}}