-
Notifications
You must be signed in to change notification settings - Fork 21.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Duplicate form authenticity tokens when more than 1 form on the page #32930
Comments
👋 Thanks for submitting this @mockdeep a few questions.
Thanks! |
Hey @gwincr11, here's a repro in a new rails app. See One thing that was interesting is that in this app the tokens duplicate even when there's only one form on the page, but that's not what I observed in another application I tried this on. |
Interesting if I change the name on the input element with the authenticity_token2 as the name then that also gets the same token. |
I think this maybe a browser implementation issue. When I curl the page into a file I get the proper html: <!DOCTYPE html>
<html>
<head>
<title>CsrfTest</title>
<meta name="csrf-param" content="authenticity_token" />
<meta name="csrf-token" content="ZjG5Kw0ty0odnmjnF4N9lIvQJUkMBs9BaIqLgC4SJxgneglcocWl0GN9XqtqyXUaKhIuLLkjQ5C2ZRH3rZdW7g==" />
<link rel="stylesheet" media="all" href="/assets/scaffolds.self-e607afa58a866f84f058a2ae3883b67629ebb713b2cc1dd8ee17a00ca4eeb50f.css?body=1" data-turbolinks-track="reload" />
<link rel="stylesheet" media="all" href="/assets/users.self-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.css?body=1" data-turbolinks-track="reload" />
<link rel="stylesheet" media="all" href="/assets/application.self-f0d704deea029cf000697e2c0181ec173a1b474645466ed843eb5ee7bb215794.css?body=1" data-turbolinks-track="reload" />
<script src="/assets/rails-ujs.self-551fbd47b981dacbb84a270f9123074caf39eb72aaf6f478ab597c6f81435e4b.js?body=1" data-turbolinks-track="reload"></script>
<script src="/assets/activestorage.self-6e8d967adecc8b2a7259df0f51ef5b6f171c33267c7d149a474beccd90c68697.js?body=1" data-turbolinks-track="reload"></script>
<script src="/assets/turbolinks.self-2db6ec539b9190f75e1d477b305df53d12904d5cafdd47c7ffd91ba25cbec128.js?body=1" data-turbolinks-track="reload"></script>
<script src="/assets/action_cable.self-69fddfcddf4fdef9828648f9330d6ce108b93b82b0b8d3affffc59a114853451.js?body=1" data-turbolinks-track="reload"></script>
<script src="/assets/cable.self-8484513823f404ed0c0f039f75243bfdede7af7919dda65f2e66391252443ce9.js?body=1" data-turbolinks-track="reload"></script>
<script src="/assets/users.self-877aef30ae1b040ab8a3aba4e3e309a11d7f2612f44dde450b5c157aa5f95c05.js?body=1" data-turbolinks-track="reload"></script>
<script src="/assets/application.self-66347cf0a4cb1f26f76868b4697a9eee457c8c3a6da80c6fdd76ff77e911715e.js?body=1" data-turbolinks-track="reload"></script>
</head>
<body>
<h1>New User</h1>
<form action="/users/new" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓" /><input type="hidden" name="authenticity_token" value="Gjs8/hM3vx8ahD7ccs3roJjhlnm+TPp9Re5ZKenBX59xFXBpFa7MnV/GxKTfOBCUsraGpZSZt8hGr148D6eUVw==" />
<input type="text" name="nada" id="nada" />
</form>
<form action="/users" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓" /><input type="hidden" name="authenticity_token" value="YnWkCeq92Lim6cViqAQv51DAXA9SA2tGM94GBk8Z0Q0Am74CY8TntXZ+Dc9Mm7Qx1oY7bQsYSU0gudNGEsDR4A==" />
<input type="hidden" name="authenticity_token" id="authenticity_token" value="3RSRR61Mchd+b+lJGQHfG+SZVTQyJPmPws7HfZrvczecXyEwAaQcjQCM3wVkS9eVRVteUYcBdV4cIV0KGWoCwQ==" />
<div class="field">
<label for="user_name">Name</label>
<input type="text" name="user[name]" id="user_name" />
</div>
<div class="field">
<label for="user_email">Email</label>
<input type="text" name="user[email]" id="user_email" />
</div>
<div class="actions">
<input type="submit" name="commit" value="Create User" data-disable-with="Create User" />
</div>
</form>5.2.0
<a href="/users">Back</a>
</body>
</html> |
Oh! I see. It's because it has |
And |
You should be able to have two forms that have the same name for an input element, that is valid HTML and when I put it into the w3c html validator it doesn't say it is invalid. |
Same issue here 🙋♂️
In addition, this refreshCSRFToken does not affect after clicking a link on turbolinks environment, because it is on DOMContentLoaded. |
This issue has been automatically marked as stale because it has not been commented on for at least three months. |
This is still an issue. I updated my repro to Rails 5.2.1, and also tested it against |
This issue has been automatically marked as stale because it has not been commented on for at least three months. |
Still an issue. |
This issue has been automatically marked as stale because it has not been commented on for at least three months. |
Same issue on Rails 5.2.3 |
@kramer33 document.addEventListener(Turbolinks.EVENTS.CHANGE, function() {
$.rails.refreshCSRFTokens();
}); |
Yes I'm using Turbolinks, but I think calling
Having different tokens in each form is a security enhancement added since Rails 5, which lower the risk of form hijacking. |
Yeah @kramer33 you are right about
But I have different issue. version is |
I ran into this on Rails 5.2.0 as well, it seems like #22275 is not working as intended when UJS is involved (specifically, the method @mastahyeti @rafaelfranca @rails/security, you all were involved in #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! 👍 |
I must say, this one caused me some confusion also. It's definitely caused by Since |
@reddyonrails I had the same issue as you. I solved it by replacing my |
Steps to reproduce
Add 2 forms to the same page with
per_form_csrf_tokens = true
andcsrf_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
The text was updated successfully, but these errors were encountered: