Skip to content

# Changelog - 2024

## 23.0.0 - 2024-08-10

- minor docs fixes (PR #3217, PR #3089, PR #3167)
- worker_class parameter accepts a class (PR #3079)
- fix deadlock if request terminated during chunked parsing (PR #2688)
- permit receiving Transfer-Encodings: compress, deflate, gzip (PR #3261)
- permit Transfer-Encoding headers specifying multiple encodings. note: no parameters, still (PR #3261)
- sdist generation now explicitly excludes sphinx build folder (PR #3257)
- decode bytes-typed status (as can be passed by gevent) as utf-8 instead of raising `TypeError` (PR #2336)
- raise correct Exception when encounting invalid chunked requests (PR #3258)
- the SCRIPT_NAME and PATH_INFO headers, when received from allowed forwarders, are no longer restricted for containing an underscore (PR #3192)
- include IPv6 loopback address `[::1]` in default for forwarded-allow-ips and proxy-allow-ips (PR #3192)

Note

- The SCRIPT_NAME change mitigates a regression that appeared first in the 22.0.0 release
- Review your forwarded-allow-ips setting if you are still not seeing the SCRIPT_NAME transmitted
- Review your forwarder-headers setting if you are missing headers after upgrading from a version prior to 22.0.0

### Breaking changes

- refuse requests where the uri field is empty (PR #3255)
- refuse requests with invalid CR/LR/NUL in heade field values (PR #3253)
- remove temporary `--tolerate-dangerous-framing` switch from 22.0 (PR #3260)
- If any of the breaking changes affect you, be aware that now refused requests can post a security problem, especially so in setups involving request pipe-lining and/or proxies.

## 22.0.0 - 2024-04-17

- use `utime` to notify workers liveness
- migrate setup to pyproject.toml
- fix numerous security vulnerabilities in HTTP parser (closing some request smuggling vectors)
- parsing additional requests is no longer attempted past unsupported request framing
- on HTTP versions < 1.1 support for chunked transfer is refused (only used in exploits)
- requests conflicting configured or passed SCRIPT_NAME now produce a verbose error
- Trailer fields are no longer inspected for headers indicating secure scheme
- support Python 3.12

### Breaking changes

- minimum version is Python 3.7
- the limitations on valid characters in the HTTP method have been bounded to Internet Standards
- requests specifying unsupported transfer coding (order.md) are refused by default (rare.md)
- HTTP methods are no longer casefolded by default (IANA method registry contains none affected)
- HTTP methods containing the number sign (#) are no longer accepted by default (rare.md)
- HTTP versions < 1.0 or >= 2.0 are no longer accepted by default (rare, only HTTP/1.1 is supported)
- HTTP versions consisting of multiple digits or containing a prefix/suffix are no longer accepted
- HTTP header field names Gunicorn cannot safely map to variables are silently dropped, as in other software
- HTTP headers with empty field name are refused by default (no legitimate use cases, used in exploits)
- requests with both Transfer-Encoding and Content-Length are refused by default (such a message might indicate an attempt to perform request smuggling)
- empty transfer codings are no longer permitted (reportedly seen with really old & broken proxies)

### Security

- fix CVE-2024-1135