rails: Duplicate form authenticity tokens when more than 1 form on the page

Steps to reproduce

Add 2 forms to the same page with per_form_csrf_tokens = true and csrf_meta_tags in the header.

Expected behavior

The CSRF token in the head and in each form will all be distinct.

Actual behavior

All 3 CSRF tokens will be the same. However, when there is only 1 form on the page, the token in the head will be distinct from the one in the head, and if we remove csrf_meta_tags from the head, all form tokens will be unique.

System configuration

Rails version: 5.2.0

Ruby version: 2.4.1

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 2
  • Comments: 21 (6 by maintainers)

Most upvoted comments

I ran into this on Rails 5.2.0 as well, it seems like https://github.com/rails/rails/pull/22275 is not working as intended when UJS is involved (specifically, the method $.rails.refreshCSRFTokens), as others have pointed out in this thread here and here.

@mastahyeti @rafaelfranca @rails/security, you all were involved in https://github.com/rails/rails/pull/22275, and I believe this PR is reporting a case where the change that intended to require per-form CSRF tokens is not working as intended. There’s a repro case, so I’m wondering why this was just closed. If you think this is too niche and not worth fixing, perhaps you could share more about that here?

Thanks! 👍

Still an issue.

Same issue here 🙋‍♂️ I think it is caused by rails-ujs’s refreshCSRFTokens() behaviour.

refreshCSRFTokens() overwrites all inputs that has name=authenticity_token when DOMContentLoaded fired. So saving page with curl does not execute JavaScript and result the proper html. (and disabling JavaScript on the browser could also reproduce a same result)

In addition, this refreshCSRFToken does not affect after clicking a link on turbolinks environment, because it is on DOMContentLoaded.

This is still an issue. I updated my repro to Rails 5.2.1, and also tested it against master, both with the same results as before.

Yeah @kramer33 you are right about

$.rails.refreshCSRFTokens() on every Turbolinks CHANGE event will not resolve this issue.

But I have different issue. When page renders with more than form I see different tokens. The form render with Turbolinks.visit() function , gives me InvalidAuthenticityToken error even though it is different token. I will keep checking this issue.

version is rails-5.2.0

Screen Shot 2019-06-10 at 10 12 19 PM

Same issue on Rails 5.2.3

Oh! I see. It’s because it has id="authenticity_token". You’re only allowed to have 1 id on the page.

🤔So I pulled down your repo and set everything up, when I inspect the authenticity tokens in the chrome web inspector I show the duplication just as you do.

However when I view source in the browser I do not see the issue. screen shot 2018-05-20 at 8 32 13 pm

This is super weird. The same thing occurs in Safari and Firefox.

So I printed them out with Javascript and JS shows them as each being the same. screen shot 2018-05-20 at 8 43 44 pm

I am going to keep digging into this but it is super weird so far.