Closed kenballus closed 4 months ago
Of particular note is that \x00
, \t
, and
are permitted, which have historically been sources of exploitable parsing discrepancies between origin servers and gateway servers.
@kenballus thanks for the report. Are you up for making a PR here?
h11 gives a regex for a header name here:
That's then validated when parsing the headers here: https://github.com/python-hyper/h11/blob/a2c68948accadc3876dffcf979d98002e4a4ed27/h11/_headers.py#L163
Gunicorn does similar here https://github.com/benoitc/gunicorn/blob/cf55d2cec277f220ebd605989ce78ad1bb553c46/gunicorn/http/message.py#L92-L93 (but matching bad headers, with what looks like a more complex regex.)
We'd handle that in the http and ws protocols:
Need to investigate whether this should be handled by twisted. https://github.com/twisted/twisted/blob/446ee139189440e890b26a29af256e9b9d0e8eba/src/twisted/web/http_headers.py
h11 test examples for no weird characters in names
are here:
Should be addressed by #500.
Thank you very much @carltongibson! I was about to start working on this just now, only to find that you've beaten me to it :)
You're welcome @kenballus. Thanks for the follow up. 🎁
The bug
RFC 9110 defines the header names must consist of a single token, which is defined as follows:
When Daphne receives a request with a header name containing any or all of the following characters, it does not reject the message:
Thus, when you send the following request:
Daphne's interpretation is as follows:
(i.e. the invalid header name made it into the request unchanged)
Nearly all other HTTP implementations reject the above request, including Uvicorn, Hypercorn, AIOHTTP, Apache httpd, Bun, CherryPy, Deno, FastHTTP, Go net/http, Gunicorn, H2O, Hyper, Jetty, libsoup, Lighttpd, Mongoose, Nginx, Node.js LiteSpeed, Passenger, Puma, Tomcat, OpenWrt uhttpd, Uvicorn, Waitress, WEBrick, and OpenBSD httpd.
Your OS and runtime environment:
pip freeze
:(Using Daphne built from main, with the latest commit being https://github.com/django/daphne/commit/993efe62ce9e9c1cd64c81b6ee7dfa7b819482c7 at the time of writing)
How you're running Channels (runserver? daphne/runworker? Nginx/Apache in front?)
Directly invoking Daphne from the command line.
Console logs and full tracebacks of any errors
N/A