Skip to content
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

Request Forgery takes relative paths into account #32770

Merged
merged 1 commit into from Feb 21, 2024

Conversation

zealot128
Copy link
Contributor

Passing relative paths into form_for and related / derived helpers led to invalid
token generations, as the tokens did not match the request.path on the
POST endpoint. Variants, such as:

form_for url: "" do

Wouldn't generate a matching csrf-token and led to an InvalidAuthenticityToken.

I've added test + code to handle the common cases, such as:

  • ""
  • "./"
  • "./post_one"
  • "post_one"

are now handled according to RFC 3986 5.2 - 5.4.

Not implemented from RFC: double dots are not handled (../../path)

relevant/ fixing issue: #31191

@hiroshi
Copy link
Contributor

hiroshi commented Aug 24, 2018

Hello Rails team,
Please give your attention to this PR!

I also stumbled upon the bug this PR is designed to fix.
I wasted half a day by digging into actionpack/lib/action_controller/metal/request_forgery_protection.rb to know per_form_csrf_tokens is the culprit... (I learnt a lot about rails csrf protection mechanism though, thanks ;-)

Also, I think it also has a security concern because if user developers of Rails cannot do workaround the bug and decided to turn off protect_from_forgery... Can you imagine?

@dillonwelch
Copy link
Contributor

@eileencodes not sure if you're aware of this PR or the linked issue or if you think it makes sense for either to have the security label.

@duyleekun
Copy link

@hiroshi You can just form_for url: request.path as @zealot128 suggested, don't disable it just yet :)

@hiroshi
Copy link
Contributor

hiroshi commented Oct 19, 2018

You can just form_for url: request.path as @zealot128 suggested, don't disable it just yet :)

The problem is not how to avoid the pitfall. I learnt where the pitfall is at least, but others can fall.
Why don't you just remove the pitfall?

@zealot128
Copy link
Contributor Author

A collegue ran into this bug again in production, after not receiving after upgrading a older client Rails app to later Rails versions... This bug might slip through test, because by default in Test there is no CSRF protection enabled.

Could a maintainer please check if this could be merged? :)

Pinging @rafaelfranca and @amatsuda because both of you had merges in that code region. Please tell me, if there is a chance to have this merged/fixed.

Base automatically changed from master to main January 14, 2021 17:00
@tonytonyjan
Copy link
Contributor

tonytonyjan commented Feb 20, 2024

hi @zealot128

I wonder if you still suffer the issue in the latest version of Rails.

@zealot128
Copy link
Contributor Author

hi @zealot128

I wonder if you still suffer the issue in the latest version of Rails.

As the method in the main branch is still the same as of 5 years ago, it would guess it would still be an issue.
In the meantime, I learned to workaround this bug and never use an empty path and always specify url: request.path or similar as the action.

I might try to revive the branch and bring it up to date, but in the last 5 years there was no interest to merge it. So my motivation is quite low. I see, my original PR here also has test files attached, so it would be possible to check those test failures for compliance with the RFC URI spec.

Passing relative paths into form_for and related helpers led to invalid
token generations, as the tokens did not match the request.path on the
POST endpoint. Variants, such as:

form_for url:
* ""
* "./"
* "./post_one"
* "post_one"

are now handled according to [RFC 3986 5.2 - 5.4](https://tools.ietf.org/html/rfc3986#section-5.2)

Limitations: double dots are not handled (../../path)

relevant issue: rails#31191
@rafaelfranca rafaelfranca merged commit db4c6db into rails:main Feb 21, 2024
4 checks passed
@zealot128
Copy link
Contributor Author

Thanks @rafaelfranca for finding the time to have a look and merge it! 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants