27 Commits

Author SHA1 Message Date
Benoit Chesneau
e223e302af test: codify field-syntax cases (RFC 9110 section 5.5 and 5.6.2) 2026-04-19 14:02:58 +02:00
Benoit Chesneau
2391901b40 test: codify chunked size/extension edge cases (RFC 9112 section 7.1) 2026-04-19 13:21:20 +02:00
Benoit Chesneau
e896a653a4 test: codify absolute-form and IPv6 authority request-target vectors (phase 2A) 2026-04-19 10:15:39 +02:00
Benoit Chesneau
f1c204626f test: codify RFC 9112 request-target and TE/CL vectors (phase 1)
Six treq fixtures covering gaps: absolute-form, asterisk-form (OPTIONS *),
authority-form (CONNECT), TE codings stacking (gzip/identity before chunked),
and the CL + TE:chunked smuggling vector.

Phase 1 of a staged corpus expansion; fixtures only, no parser changes.
2026-04-19 09:52:15 +02:00
Benoit Chesneau
4ce6aa1f3e Fix limit handling and add default max limit tests
- LimitRequestLine now accepts optional max_size parameter
- Use default max limits when limit_request_line or limit_request_field_size is 0
- Add tests validating default max enforcement (8190 bytes)
- Handle alternate exceptions from fast parser in test_invalid_requests
2026-03-22 16:17:55 +01:00
Benoit Chesneau
95b7ffeeaa chore: prepare release 25.0.2
- Bump version to 25.0.2
- Update copyright year to 2026 in LICENSE and NOTICE
- Add license headers to all Python source files
- Add changelog entry for 25.0.2
2026-02-06 08:21:18 +01:00
Benoit Chesneau
f3190f84cc
feat: add PROXY protocol v2 support with version selection (#3451)
Extend --proxy-protocol to accept version values (off, v1, v2, auto) instead
of being boolean-only. This allows explicit control over which PROXY protocol
versions are accepted.

Changes:
- Add InvalidProxyHeader exception for v2 binary header errors
- Add validate_proxy_protocol() validator with backwards compatibility
- Update ProxyProtocol setting with nargs="?" and const="auto"
- Add PROXY v2 constants (PP_V2_SIGNATURE, PPCommand, PPFamily, PPProtocol)
- Add _parse_proxy_protocol_v1() and _parse_proxy_protocol_v2() methods
- Update both sync (message.py) and async (asgi/message.py) parsers
- Add hex escape handling in treq.py for v2 binary test data
- Add test cases for v2 TCPv4 and TCPv6

Backwards compatible: --proxy-protocol alone (or True) maps to "auto".

Closes #2912
2026-01-23 18:40:44 +01:00
Paul J. Dorn
2bc931e7d9 whitespace handling in header field values
Strip whitespace also *after* header field value.
Simply refuse obsolete header folding (a default-off
option to revert is temporarily provided).
While we are at it, explicitly handle recently
introduced http error classes with intended status code.
2024-08-07 19:42:16 +02:00
benoitc
555d2fa27f don't tolerate wrong te headers
changes:

- Just follow the new TE specification (https://datatracker.ietf.org/doc/html/rfc9112#name-transfer-encoding)
 here and accept to introduce a breaking change.
- gandle multiple TE on one line

** breaking changes ** : invalid  headers and position will now return
an error.
2024-08-06 23:47:01 +02:00
Paul J. Dorn
eda9d456d3 forbid lone CR/LF and NUL in headers
New parser rule: refuse HTTP requests where a header field value
contains characters that
a) should never appear there in the first place,
b) might have lead to incorrect treatment in a proxy in front, and
c) might lead to unintended behaviour in applications.

From RFC 9110 section 5.5:
"Field values containing CR, LF, or NUL characters are invalid and
dangerous, due to the varying ways that implementations might parse
and interpret those characters; a recipient of CR, LF, or NUL within
a field value MUST either reject the message or replace each of those
characters with SP before further processing or forwarding of that
message."
2024-07-31 01:28:30 +02:00
Paul J. Dorn
e710393d14 HTTP parser: stricter chunk-ext OBS handling
chunk extensions are silently ignored before and after this change;
its just the whitespace handling for the case without extensions that matters
applying same strip(WS)->rstrip(BWS) replacement as already done in related cases

half-way fix: could probably reject all BWS cases, rejecting only misplaced ones
2023-12-17 17:46:56 +01:00
Paul J. Dorn
ac29c9b0a7 fail-safe on unsupported request framing
If we promise wsgi.input_terminated, we better get it right - or not at all.
* chunked encoding on HTTP <= 1.1
* chunked not last transfer coding
* multiple chinked codings
* any unknown codings (yes, this too! because we do not detect unusual syntax that is still chunked)
* empty coding (plausibly harmless, but not see in real life anyway - refused, for the moment)
2023-12-15 13:33:31 +01:00
Paul J. Dorn
72b8970dbf silently drop or refuse header names w/ underscore
Ambiguous mappings open a bottomless pit of "what is user input and what is proxy input" confusion.
Default to what everyone else has been doing for years now, silently drop.

see also https://nginx.org/r/underscores_in_headers
2023-12-15 13:33:31 +01:00
Paul J. Dorn
b2846783d7 strict: header field validation: stop casefolding
* refusing lowercase and ASCII 0x23 (#) had been partially enforced before
* do not casefold by default, HTTP methods are case sensitive
2023-12-15 13:33:31 +01:00
Ben Kallus
72238fcf8d RFC compliant request line and header parsing
- Unify HEADER_RE and METH_RE
- Replace CRLF with SP during obs-fold processing (See RFC 9112 Section 5.2, last paragraph)
- Stop stripping header names.
- Remove HTAB in OWS in header values that use obs-fold (See RFC 9112 Section 5.2, last paragraph)
- Use fullmatch instead of search, which has problems with empty strings. (See GHSA-68xg-gqqm-vgj8)
- Split proxy protocol line on space only. (See proxy protocol Section 2.1, bullet 3)
- Use fullmatch for method and version (Thank you to Paul Dorn for noticing this.)
- Replace calls to str.strip() with str.strip(' \t')
- Split request line on SP only.

Co-authored-by: Paul Dorn <pajod@users.noreply.github.com>
2023-12-15 13:33:31 +01:00
Emile Fugulin
f74324bd75 Handle multiple transfer-encoding 2019-11-18 22:29:02 -05:00
Emile Fugulin
b798412444 Remove default strip of header name 2019-11-18 19:44:01 -05:00
YuppY
5953148573 Do not strip leading slash from path (#1511)
Fixes #1512
2017-12-28 11:32:47 +03:00
Raphaël Slinckx
15e901a5e5 http/message: Split request line as bytes to avoid splitting on 0x0A. Fixes #1577 2017-08-25 10:50:34 +02:00
Tobias Gustafsson
70cfb0d818 Remove upper limit on max header size config (#1313)
Fixes #1306
2016-09-17 12:49:05 +03:00
George Notaras
2d7eb3dc04 Added extra valid request (099) and test (send_special_chunks).
``send_special_chunks`` sends the request data in two chunks, one having a length of 1 byte, which ensures there is no CRLF, and a second chunk containing the rest of the request data. Practically, this forces ``gunicorn.http.message.Request.read_line()`` to get the full request data with two buffer reads and reveal possible bugs related to the internal buffer mechanism. See #670 for more information.
2013-12-30 00:14:46 +02:00
benoitc
8d453fb341 all tests pass under python 3 2012-10-24 22:07:35 +02:00
Konstantin Kapustin
70534acde8 Implantation proxy protocol 2012-09-27 19:14:40 +02:00
Konstantin Kapustin
4be3282440 Check Content-Length header.
For not chunked request do validation Content-Length header and return 400 if invalid.
2012-09-27 19:14:40 +02:00
benoitc
d79ff999ce fix multiple issues with request limit
patch from Djoume Salvetti . address the following issues in gunicorn:

* Gunicorn does not limit the size of a request header (the
* limit_request_field_size configuration parameter is not used)

* When the configured request limit is lower than its maximum value, the
* maximum value is used instead. For instance if limit_request_line is
* set to 1024, gunicorn will only limit the request line to 4096 chars
* (this issue also affects limit_request_fields)

* Request limits are not limited to their maximum authorized values. For
* instance it is possible to set limit_request_line to 64K (this issue
* also affects limit_request_fields)

* Setting limit_request_fields and limit_request_field_size to 0 does
* not make them unlimited. The following patch allows limit_request_line
* and limit_request_field_size to be unlimited. limit_request_fields can
* no longer be unlimited (I can't imagine 32K fields to not be enough
* but I have a use case where 8K for the request line is not enough).

* Parsing errors (premature client disconnection) are not reported

* When request line limit is exceeded the configured value is reported
* instead of the effective value.
2012-05-24 12:13:34 +02:00
benoitc
b7b0979ad9 check if Request Line is too large.
You can now pass the parameter --limit-request-line or set the
limit_request_line in your configuration file to set the max size of the
request line in bytes.

This parameter is used to limit the allowed size of a client's HTTP
request-line. Since the request-line consists of the HTTP method, URI,
and protocol version, this directive places a restriction on the length
of a request-URI allowed for a request on the server. A server needs
this value to be large enough to hold any of its resource names,
including any information that might be passed in the query part of a
GET request. By default this value is 4094 and can't be larger than
8190.

This parameter can be used to prevent any DDOS attack.
2012-02-20 09:56:06 +01:00
Paul J. Davis
5af1273fc2 Added more valid request tests.
Found and fixed a couple read and readline related bugs.
2010-06-03 16:11:18 -04:00