Skip to content

Conversation

@touchweb-vincent
Copy link
Contributor

@touchweb-vincent touchweb-vincent commented Nov 14, 2025

Hello,

I think this unit test is misleading - in real-word context, rule 920180 is not triggered by this payload :

curl -v --http2 -H "x-format-output: txt-matched-rules" -H "x-crs-paranoia-level:4" "http://sandbox.coreruleset.org/" -d '{"id_order":"select(sleep(10));"}' -H 'Content-Type:' -H 'Content-Length:'

920180 PL1 POST without Content-Length or Transfer-Encoding headers

This is a content-type evasion bypass to avoid these rules :

curl -v --http2 -H "x-format-output: txt-matched-rules" -H "x-crs-paranoia-level:4" "http://sandbox.coreruleset.org/" -d '{"id_order":"select(sleep(10));"}' -H 'Content-Type:application/json'

920273 PL4 Invalid character in request (outside of very strict set)
933161 PL3 PHP Injection Attack: Low-Value PHP Function Call Found
942100 PL1 SQL Injection Attack Detected via libinjection
942160 PL1 Detects blind sqli tests using sleep() or benchmark()
942150 PL2 SQL Injection Attack: SQL function name detected
942410 PL2 SQL Injection Attack
942432 PL4 Restricted SQL Character Anomaly Detection (args): # of special characters exceeded (2)

This payload targets backends that use file_get_contents('php://input');, which is common in AJAX transactions (especially in the PrestaShop ecosystem).

PR available here for mitigation : #4341


I don’t think this rule (920180) is actually useful in its current state.

If you agree, I’d suggest a rewrite - among the rules we have here regarding evasions, we completely forbid the use of PATCH, POST, or PUT methods being sent without a Content-Type header.

What do you think ?

@github-actions
Copy link
Contributor

github-actions bot commented Nov 14, 2025

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

@fzipi
Copy link
Member

fzipi commented Nov 14, 2025

Very interesting find!

@fzipi
Copy link
Member

fzipi commented Nov 14, 2025

Regarging the tests... I think go-ftw won't actually use http2 as a client and just use http/1.1 with the HTTP/2.0 as the protocol 🤔

@fzipi
Copy link
Member

fzipi commented Nov 14, 2025

here's what the HTTP RFCs say about using PATCH, POST, or PUT methods without a Content-Type header:

RFC 9110 / RFC 7231 (General HTTP Semantics)

The HTTP specification IETF IETF states that a sender that generates a message containing content (payload body) SHOULD generate a Content-Type header field in that message unless the intended media type of the enclosed representation is unknown to the sender.

If a Content-Type header field is not present, the recipient MAY either assume a media type of "application/octet-stream" or examine the data to determine its type. IETFIETF

Key points:

  • SHOULD (not MUST) - This means it's strongly recommended but not strictly required
  • The exception is when the media type is unknown to the sender
  • Recipients have options for handling missing Content-Type headers

RFC 5789 (PATCH Method)

For the PATCH method specifically, the set of changes is represented in a format called a "patch document" identified by a media type.
RFC 5789 - PATCH Method for HTTP +2
While RFC 5789 doesn't explicitly require a Content-Type header, an official erratum clarifies that the means of applying a PATCH request to a resource's state is determined by the request's media type, and servers SHOULD reject PATCH requests with a 415 (Unsupported Media Type) status code if they receive a media type whose specification does not define PATCH semantics
RFC Editor.

Practical Implications

  • Content-Type is not strictly mandatory - The spec uses "SHOULD" rather than "MUST"
  • Strong recommendation - You should include it whenever possible for interoperability
  • PATCH is special - For PATCH specifically, the Content-Type is crucial because it determines how to interpret the patch document (e.g., application/json-patch+json vs application/merge-patch+json)
  • Server behavior varies - Some strict implementations may return a 415 error without Content-Type, while others may make assumptions

Best practice: Always include the Content-Type header for POST, PUT, and PATCH requests that contain a body, even though it's not strictly required by the specification.

@fzipi
Copy link
Member

fzipi commented Nov 14, 2025

I assume this opens also a pandora's box regarding the default accepted types for PATCH.

@theseion
Copy link
Contributor

The rule targets requests < HTTP/2, which is why your payloads don't match. That being said, you're right, both the documentation and the test are wrong. We haven't yet implemented HTTP/2 in go-ftw, so we can't test anything with a protocol version other than HTTP/1.1.

If we start blocking that behaviour, we need to make it configurable through crs-setup.conf. I think it's worth a discussion.

@fzipi
Copy link
Member

fzipi commented Nov 15, 2025

Added coreruleset/go-ftw#556 as follow-up to see what we can do.

@theseion theseion added this pull request to the merge queue Nov 16, 2025
Merged via the queue into coreruleset:main with commit dc9a268 Nov 16, 2025
7 checks passed
@touchweb-vincent touchweb-vincent deleted the patch-21 branch November 16, 2025 19:52
@fzipi fzipi mentioned this pull request Dec 1, 2025
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.

3 participants