caddyhttp: Introduce strict HTTP mode (WIP) #4841
Closed
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
It has come up several times that across various parts of the HTTP app, malformed requests can cause problems. They're not necessarily direct security issues, but can have unintended consequences for upstream/backend applications that are being proxied to, or file systems with flimsy rules for filepaths, etc., when combined with the wrong configs.
In an effort to reduce possible misconfigurations and edge cases with various other systems like backend services and file systems, I'm proposing a kind of "strict HTTP mode" to be enabled by default. (This PR is still in a draft/WIP state. Feedback and discussion is invited.)
It will reject requests with HTTP 400 that have:
;
in the query string//
,..
, orNUL
(%00
or\x00
) in the path (see fastcgi: Possible Arbitrary Code Execution with Null Bytes, PHP, Windows #4574 and Problem with path matching and URI manipulation when involving double slashes #4743; would supersede fastcgi: Protect against requests with null bytes in the path #4614)_
) (see Allow blocking headers with underscores #4830)Basically the idea of strict HTTP is to enforce clean, spec-compliant requests and reject all others.
To clarify, I'm not saying this is a good idea or that the web server/proxy should be responsible for this. In fact I am pretty sure this will break a few legitimate use cases and applications, which do want underscores in some header fields or which use semicolons in the query string or which require double slashes for some sort of semantic interpretation.
As mentioned, these qualities of an HTTP requests are not in and of themselves security vulnerabilities, but they can present problems from poorly-designed or buggy applications that depend on these parts of HTTP requests. (For example, a file server that does not sanitize the path could be vulnerable to directory traversal by blindly evaluating
..
components in the path. Or Django apps can be misled by clients adding aHOST_HEADER
header field. Or Windows file systems do unexpected things with NUL bytes. Merely having..
in a path is not a security problem for Caddy, nor is having a header calledHOST_HEADER
, and so on.)This implementation is currently WIP. It enables the enforcement of these traits by default, but can be disabled entirely or piecewise by being lenient on query strings, paths, or headers according to your configuration.
Upsides:
Downsides:
The whole change is not my favorite, and that last point is really bothering me.
Instead of this change, I recommend that applications actually patch their vulnerabilities.