Skip to content

Reject requests that have duplicate Content-Type / Host headers#3548

Open
Cycloctane wants to merge 9 commits intobenoitc:masterfrom
Cycloctane:reject-duplicate-headers
Open

Reject requests that have duplicate Content-Type / Host headers#3548
Cycloctane wants to merge 9 commits intobenoitc:masterfrom
Cycloctane:reject-duplicate-headers

Conversation

@Cycloctane
Copy link
Copy Markdown

@Cycloctane Cycloctane commented Mar 20, 2026

Duplicate Content-Type and Host headers in requests are not allowed in RFC9110 and can cause security concerns. This PR makes parse_headers() raise InvalidHeader on these malformed requests.

Fixes #3366

currently only Host, Content-Length and Content-Type are rejected as they
are more likely to cause security issues.

also move headers merging from wsgi to http header parser
since duplicated headers now are merged in parse_headers
tests/requests/valid/030 is exactly the same as 029
Copy link
Copy Markdown
Contributor

@pajod pajod left a comment

Choose a reason for hiding this comment

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

This swaps mapping/merging order. This results in meaningful header content change for accepted requests while only justifying the decision to reject some requests. Some test like tests/requests/valid/040_compat.http - but actually testing the edge case - would need to be added.

Comment thread gunicorn/http/wsgi.py
Copy link
Copy Markdown
Owner

@benoitc benoitc left a comment

Choose a reason for hiding this comment

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

Thanks for your PR! Please check my comment. Also I think it should be an option. Some servers rely on multiple headers. Can you do the changes?

Comment thread gunicorn/http/message.py Outdated
def parse_headers(self, data, from_trailer=False):
cfg = self.cfg
headers = []
headers = {}
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

thois would break the header order. If you want to check an unicity i would rather use a last seen pattern or equivalent like it's done for some headers. Also we need to keep compatibility with some weird behaviour. So I would just use it for content type and host headers

This comment was marked as outdated.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I've reconsidered my approach. "Last seen" pattern is indeed cleaner for this PR. I've updated my changes. Thanks for your review :)

@Cycloctane
Copy link
Copy Markdown
Author

@benoitc Sorry for the delay. It seems that the project was refactored. Should we add duplicated headers checks for the new http c parser to gunicorn_h1c? Then I would like to open a pr in that repository also.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Duplicate Content-Type Header Parsing Issue

3 participants