Skip to content

feat(920650): add detection for framework method overrides#4416

Merged
fzipi merged 6 commits into
mainfrom
feat/method-override-frameworks
Jan 26, 2026
Merged

feat(920650): add detection for framework method overrides#4416
fzipi merged 6 commits into
mainfrom
feat/method-override-frameworks

Conversation

@fzipi
Copy link
Copy Markdown
Member

@fzipi fzipi commented Jan 21, 2026

what

This PR adds a new rule (920650) to detect HTTP method override attempts via the _method parameter in query strings and request bodies.

New components:

  1. Rule 920650 (REQUEST-920-PROTOCOL-ENFORCEMENT.conf, PL2): Detects _method parameter containing dangerous HTTP methods (DELETE, PUT, PATCH, OPTIONS, TRACE, TRACK, CONNECT, HEAD, DEBUG)

  2. Rule 901510 (REQUEST-901-INITIALIZATION.conf): Initializes tx.allow_method_override_parameter to 0

  3. Configuration option 900210 (crs-setup.conf.example): Allows users to permit _method parameter usage for applications that legitimately require it

  4. Test suite (tests/regression/tests/REQUEST-920-PROTOCOL-ENFORCEMENT/920650.yaml): 32 test cases covering positive and negative scenarios

why

The _method parameter is a method override mechanism supported by many popular web frameworks including Laravel, Ruby on Rails, Symfony, CakePHP, Express.js, Phoenix, and others. While this is legitimate framework functionality designed to work around HTML form limitations (forms only support GET and POST), it can be abused for:

  1. WAF Bypass: An attacker sends a POST request with _method=DELETE. The WAF sees a POST request and applies POST-related rules, but the application processes it as DELETE, potentially bypassing method-specific security controls.

  2. CSRF via SameSite=Lax Bypass: Browsers send cookies for top-level GET navigations under SameSite=Lax. An attacker can craft GET /transfer?amount=1000&_method=POST which the browser treats as GET (sending cookies) but the application processes as POST, enabling CSRF attacks.

  3. ACL Bypass: Applications with method-based access controls (e.g., "only admins can DELETE") can be circumvented when the actual HTTP method doesn't match what the application processes.

CRS already blocks method override via HTTP headers (X-HTTP-Method-Override, X-HTTP-Method, X-Method-Override) in rule 920450. This PR complements that coverage by addressing the parameter-based vector, providing comprehensive protection against method override attacks.

refs

Signed-off-by: Felipe Zipitria <felipe.zipitria@owasp.org>
@fzipi fzipi requested review from a team and theseion January 21, 2026 13:53
@fzipi fzipi added the release:new-detection In this PR we introduce a new detection label Jan 21, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jan 21, 2026

📊 Quantitative test results for language: eng, year: 2023, size: 10K, paranoia level: 1:
🚀 Quantitative testing did not detect new false positives

@fzipi
Copy link
Copy Markdown
Member Author

fzipi commented Jan 21, 2026

The only doubt I might have is if we do it the other way around. E.g. we disable the detection initially, and users need to enable. 🤔

@EsadCetiner
Copy link
Copy Markdown
Member

@fzipi Wouldn't it make more sense to only use an allow-list here instead of just blacklisting dangerous methods? The second example you gave is currently not covered by the new rule you've added.

@fzipi
Copy link
Copy Markdown
Member Author

fzipi commented Jan 22, 2026

The idea is just detecting, not blacklisting I guess. We can, if you want, remove those in our own allowed list. But the idea is using cross methods, right?

Comment thread rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf Outdated
@EsadCetiner
Copy link
Copy Markdown
Member

@fzipi I'm just thinking ahead here when new methods are introduced or if we simply just missed one. It would be more robust against bypasses.

@fzipi
Copy link
Copy Markdown
Member Author

fzipi commented Jan 22, 2026

Ok, we already use generic matching at PL1 in

^[a-z]{3,10}\s+(?:\w{3,7}?://[\w\-\./]*(?::\d+)?)?/[^?#]*(?:\?[^#\s]*)?(?:#[\S]*)?\s+[\w\./]+$
We can do a similar thing here. I meant, use ^[a-z]{3,10}.

@fzipi
Copy link
Copy Markdown
Member Author

fzipi commented Jan 22, 2026

@fzipi I'm just thinking ahead here when new methods are introduced or if we simply just missed one. It would be more robust against bypasses.

I agree with this in general, but then we should review methods every X time, right? Could be part of out "lists" update.

@EsadCetiner
Copy link
Copy Markdown
Member

@fzipi

I agree with this in general, but then we should review methods every X time, right? Could be part of out "lists" update.

You lost me here, why should we review the methods or update them if we're using a generic match? There is no list to update.

@fzipi
Copy link
Copy Markdown
Member Author

fzipi commented Jan 23, 2026

Ok. If we do a "generic regex", we might get some false positives. A more controlled list might get us less FPs, but then we need to update.

Let's go for the generic regex, and see where we get. Hopefully, those people using PHP can test and tell us if it is too aggressive.

@EsadCetiner
Copy link
Copy Markdown
Member

@fzipi We could have the generic match at PL-3 in that case, and an denylist approach at PL-2.

Hopefully, those people using PHP can test and tell us if it is too aggressive.

FYI I've also seen this on GitLab which uses Ruby and not PHP. Based on the tests I have for the GitLab plugin I'm working on so far, only the patch and put method is being sent.

Signed-off-by: Felipe Zipitria <felipe.zipitria@owasp.org>
EsadCetiner
EsadCetiner previously approved these changes Jan 24, 2026
Copy link
Copy Markdown
Member

@EsadCetiner EsadCetiner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Also, we're now no longer specifying individual test authors, just "OWASP CRS Team"?

Comment thread tests/regression/tests/REQUEST-920-PROTOCOL-ENFORCEMENT/920650.yaml Outdated
@fzipi
Copy link
Copy Markdown
Member Author

fzipi commented Jan 24, 2026

LGTM

Also, we're now no longer specifying individual test authors, just "OWASP CRS Team"?

Nah, it is a good catch: my template for tests creates that automatically.

@fzipi fzipi added this pull request to the merge queue Jan 26, 2026
Merged via the queue into main with commit 114ff56 Jan 26, 2026
8 checks passed
@fzipi fzipi deleted the feat/method-override-frameworks branch January 26, 2026 12:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release:new-detection In this PR we introduce a new detection

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants