31 Commits

Author SHA1 Message Date
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
7ebe442d08 strict HTTP version validation
Note: This is unrelated to a reverse proxy potentially talking HTTP/3 to clients.
This is about the HTTP protocol version spoken to Gunicorn, which is HTTP/1.0 or HTTP/1.1.

Little legitimate need for processing HTTP 1 requests with ambiguous version numbers.
Broadly refuse.

Co-authored-by: Ben Kallus <benjamin.p.kallus.gr@dartmouth.edu>
2023-12-15 13:33:31 +01:00
Paul J. Dorn
f5501111a2 strict HTTP header field name validation
Do the validation on the original, not the result from unicode case folding.

Background:
latin-1 0xDF is traditionally uppercased 0x53+0x53 which puts it back in ASCII
2023-12-15 13:33:31 +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
Jason Myers
fa94f70529 Updating Content-Length Handling
Signed-off-by: Jason Myers <jmyers@syntellis.com>
2023-05-30 20:42:13 -05:00
Emile Fugulin
ddf5e66ac8 Remove strict check of Transfer-Encoding 2019-11-20 12:25:39 -05:00
Emile Fugulin
f74324bd75 Handle multiple transfer-encoding 2019-11-18 22:29:02 -05:00
Emile Fugulin
bd8670b4db Handle duplicate content-length 2019-11-18 21:16:12 -05:00
Emile Fugulin
b798412444 Remove default strip of header name 2019-11-18 19:44:01 -05:00
Randall Leeds
b07532be75 Forbid contradictory secure scheme headers
When a request specifies contradictory secure scheme headers, raise a
parse error.
2018-01-10 12:10:35 -08: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
Your Name
a912e305c9 Reject requests like "GET / HTTP/1a1"
Numbers must be separated by dot. This makes life
a little bit harder for attackers who would like to inject specially crafted packets after GET / (e.g. in nginx there are sometimes regular expressions like (?P<action>[^.]).html
2016-11-04 21:16:01 +03:00
Tobias Gustafsson
70cfb0d818 Remove upper limit on max header size config (#1313)
Fixes #1306
2016-09-17 12:49:05 +03:00
Randall Leeds
72c8be56fc Add test for #1023 2015-05-09 20:46:31 +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
7a1c58f236 test number of headers fields and size.
Add --limit-request-fields (limit_request_fields) and
--limit-request-field-size (limit-request-field-size) options.

- limit_request_fields:

    Value is a number from 0 (unlimited) to 32768. This parameter is
    used to limit the number of headers in a request to prevent DDOS
    attack. Used with the `limit_request_field_size` it allows more
    safety.

- limit_request_field_size:

    Value is a number from 0 (unlimited) to 8190. to set the limit
    on the allowed size of an HTTP request header field.
2012-02-20 10:36:13 +01: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
Paul J. Davis
27cc404f1f Imported simplehttp request tests. 2010-06-03 16:11:17 -04:00
Paul J. Davis
588b48b2cd Comma separate repeated request headers.
RFC 2616 says that only headers that are allowed to have comma separated
values are acceptable for repetition. Though it doesn't specify an error
condition for that situation. I reckon the cleanest way would be to list
the headers that are acceptable for repetition, and return a 400 Bad
Request.
2010-02-10 10:55:09 -05:00
Benoit Chesneau
bfeb4f9416 fix chunked encoding and add tests 2010-01-20 16:21:20 +01:00
Benoit Chesneau
d4ae13cde0 forgot to commit tests 2010-01-20 15:21:57 +01:00