From 18c5cb10d98479b862f9cd0711abeb878214d703 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Mon, 29 Sep 2025 18:42:11 +0100 Subject: [PATCH 1/3] Ruby: Update CSRF protection notes in documentation 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. --- .../queries/security/cwe-352/CSRFProtectionDisabled.qhelp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ruby/ql/src/queries/security/cwe-352/CSRFProtectionDisabled.qhelp b/ruby/ql/src/queries/security/cwe-352/CSRFProtectionDisabled.qhelp index 7656a676d647..138ff588ac53 100644 --- a/ruby/ql/src/queries/security/cwe-352/CSRFProtectionDisabled.qhelp +++ b/ruby/ql/src/queries/security/cwe-352/CSRFProtectionDisabled.qhelp @@ -58,6 +58,11 @@ for example if parts of the session are memoized. Calling protect_from_forgery with: :exception can help to avoid this by raising an exception on an invalid CSRF token instead. + Note this remains true even in Rails version 5 and later: these versions + automatically run protect_from_forgery with: :exception + by default, but manually calling protect_from_forgery with + no with argument will still downgrade protection to null the + session rather than raise an exception.

From f1239352cefe57081023951bda21a898fb495321 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Mon, 29 Sep 2025 18:43:59 +0100 Subject: [PATCH 2/3] Note issue in related query --- .../queries/security/cwe-352/CSRFProtectionNotEnabled.qhelp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ruby/ql/src/queries/security/cwe-352/CSRFProtectionNotEnabled.qhelp b/ruby/ql/src/queries/security/cwe-352/CSRFProtectionNotEnabled.qhelp index 9b8944b1d65c..5af4be5c7ecf 100644 --- a/ruby/ql/src/queries/security/cwe-352/CSRFProtectionNotEnabled.qhelp +++ b/ruby/ql/src/queries/security/cwe-352/CSRFProtectionNotEnabled.qhelp @@ -42,6 +42,12 @@ vulnerability - for example if parts of the session are memoized. Calling protect_from_forgery with: :exception can help to avoid this by raising an exception on an invalid CSRF token instead. + + Note that Rails version 5 and later + automatically run protect_from_forgery with: :exception + by default, but manually calling protect_from_forgery with + no with argument will downgrade protection to null the + session rather than raise an exception.

From ff4b97bf2d329001dae6e6572008bcd46b68f369 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Tue, 30 Sep 2025 13:08:03 +0100 Subject: [PATCH 3/3] Reword --- .../src/queries/security/cwe-352/CSRFProtectionDisabled.qhelp | 4 ++-- .../queries/security/cwe-352/CSRFProtectionNotEnabled.qhelp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ruby/ql/src/queries/security/cwe-352/CSRFProtectionDisabled.qhelp b/ruby/ql/src/queries/security/cwe-352/CSRFProtectionDisabled.qhelp index 138ff588ac53..f14f04de57fc 100644 --- a/ruby/ql/src/queries/security/cwe-352/CSRFProtectionDisabled.qhelp +++ b/ruby/ql/src/queries/security/cwe-352/CSRFProtectionDisabled.qhelp @@ -61,8 +61,8 @@ Note this remains true even in Rails version 5 and later: these versions automatically run protect_from_forgery with: :exception by default, but manually calling protect_from_forgery with - no with argument will still downgrade protection to null the - session rather than raise an exception. + no with argument will still downgrade protection to provide an + empty session rather than raise an exception.

diff --git a/ruby/ql/src/queries/security/cwe-352/CSRFProtectionNotEnabled.qhelp b/ruby/ql/src/queries/security/cwe-352/CSRFProtectionNotEnabled.qhelp index 5af4be5c7ecf..5cbbbd1eea16 100644 --- a/ruby/ql/src/queries/security/cwe-352/CSRFProtectionNotEnabled.qhelp +++ b/ruby/ql/src/queries/security/cwe-352/CSRFProtectionNotEnabled.qhelp @@ -43,10 +43,10 @@ protect_from_forgery with: :exception can help to avoid this by raising an exception on an invalid CSRF token instead. - Note that Rails version 5 and later + Note that Rails versions 5 and later automatically run protect_from_forgery with: :exception by default, but manually calling protect_from_forgery with - no with argument will downgrade protection to null the + no with argument will downgrade protection to provide an empty session rather than raise an exception.