-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Ruby: Update CSRF protection notes in documentation #20550
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
base: main
Are you sure you want to change the base?
Conversation
Autofix is confused about how the `protect_from_forgery` method works in Rails >= 5: GPT-5 says: > In modern Rails versions (>=5, including 6 and 7 which this gem permits), ActionController::Base already enables CSRF protection by default with the `:exception` strategy; an explicit call to `protect_from_forgery` without options does not weaken security. This is false: manual testing confirms that it actually does downgrade from `:exception` to `:null-session` behaviour when a manual call is made. I can't find any authoritative source showing this gotcha, so I can see how the AI is confused and how humans might also struggle to verify the truth.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR updates documentation for the CSRF protection disabled query to clarify how Rails' protect_from_forgery
method behaves in version 5 and later. The change corrects a common misconception about the default behavior of manual protect_from_forgery
calls.
Key Changes
- Adds clarification that Rails 5+ defaults to
:exception
strategy for CSRF protection - Documents that manually calling
protect_from_forgery
without arguments downgrades to:null_session
behavior - Addresses confusion about how explicit calls interact with Rails' automatic protection
Note this remains true even in Rails version 5 and later: these versions | ||
automatically run <code>protect_from_forgery with: :exception</code> | ||
by default, but manually calling <code>protect_from_forgery</code> with | ||
no <code>with</code> argument will still downgrade protection to null the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The phrase 'null the session' is grammatically incorrect. It should be 'nullify the session' or 'set the session to null'.
Copilot uses AI. Check for mistakes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that this reads a bit weird.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reworded.
QHelp previews: ruby/ql/src/queries/security/cwe-352/CSRFProtectionDisabled.qhelpCSRF protection weakened or disabledCross-site request forgery (CSRF) is a type of vulnerability in which an attacker is able to force a user to carry out an action that the user did not intend. The attacker tricks an authenticated user into submitting a request to the web application. Typically this request will result in a state change on the server, such as changing the user's password. The request can be initiated when the user visits a site controlled by the attacker. If the web application relies only on cookies for authentication, or on other credentials that are automatically included in the request, then this request will appear as legitimate to the server. A common countermeasure for CSRF is to generate a unique token to be included in the HTML sent from the server to a user. This token can be used as a hidden field to be sent back with requests to the server, where the server can then check that the token is valid and associated with the relevant user session. RecommendationIn many web frameworks, CSRF protection is enabled by default. In these cases, using the default configuration is sufficient to guard against most CSRF attacks. ExampleThe following example shows a case where CSRF protection is disabled by skipping token verification. class UsersController < ApplicationController
skip_before_action :verify_authenticity_token
end Verification can be re-enabled by removing the call to Care should be taken when using the Rails References
ruby/ql/src/queries/security/cwe-352/CSRFProtectionNotEnabled.qhelpCSRF protection not enabledCross-site request forgery (CSRF) is a type of vulnerability in which an attacker is able to force a user to carry out an action that the user did not intend. The attacker tricks an authenticated user into submitting a request to the web application. Typically this request will result in a state change on the server, such as changing the user's password. The request can be initiated when the user visits a site controlled by the attacker. If the web application relies only on cookies for authentication, or on other credentials that are automatically included in the request, then this request will appear as legitimate to the server. A common countermeasure for CSRF is to generate a unique token to be included in the HTML sent from the server to a user. This token can be used as a hidden field to be sent back with requests to the server, where the server can then check that the token is valid and associated with the relevant user session. RecommendationIn the Rails web framework, CSRF protection is enabled by the adding a call to the ExampleThe following example shows a case where CSRF protection is enabled with a secure request handling strategy of class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
end
References
|
by raising an exception on an invalid CSRF token instead. | ||
|
||
Note that Rails version 5 and later | ||
automatically run <code>protect_from_forgery with: :exception</code> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
run -> runs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed version -> versions instead
Note this remains true even in Rails version 5 and later: these versions | ||
automatically run <code>protect_from_forgery with: :exception</code> | ||
by default, but manually calling <code>protect_from_forgery</code> with | ||
no <code>with</code> argument will still downgrade protection to null the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that this reads a bit weird.
Autofix is confused about how the
protect_from_forgery
method works in Rails >= 5: GPT-5 says:This is false: manual testing confirms that it actually does downgrade from
:exception
to:null-session
behaviour when a manual call is made.I can't find any authoritative source showing this gotcha, so I can see how the AI is confused and how humans might also struggle to verify the truth.