Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Whitespace is incorrectly stripped from the ends of header names, before the : #2016

Closed
1 of 3 tasks
kenballus opened this issue Feb 4, 2024 · 6 comments
Closed
1 of 3 tasks

Comments

@kenballus
Copy link

I'm submitting a ...

  • bug report
  • feature request
  • question about the decisions made in the repository

Do you want to request a feature or report a bug?
Report a bug.

What is the current behavior?
CherryPy strips whitespace from the ends of header names.

If the current behavior is a bug, please provide the steps to reproduce and if possible a screenshots and logs of the problem. If you can, show us your code.

  1. Start up a CherryPy-based web application that echos back the received message body. Here's one.
  2. Send it a request with a space after the Content-Length header, before the :, such as the following:
POST / HTTP/1.1\r\n
Host: whatever\r\n
Content-Length : 1\r\n
\r\n
Z
  1. Observe that CherryPy sees a message body of Z, indicating that it stripped the space from the end of the header name.

What is the expected behavior?
RFC 9112, section 5.1 requires that requests with space after header names MUST be rejected:

No whitespace is allowed between the field name and colon. In the past, differences in the handling of such whitespace have led to security vulnerabilities in request routing and response handling. A server MUST reject, with a response status code of 400 (Bad Request), any received request message that contains whitespace between a header field name and colon.

What is the motivation / use case for changing the behavior?
In the past, differences in the handling of such whitespace have led to security vulnerabilities in request routing and response handling.

Please tell us about your environment:

  • Cheroot version: 10.0.0
  • CherryPy version: 18.9.1.dev25+g6387a2b8
  • Python version: 3.11.2
  • OS: Linux 29deec81efdd 6.7.2-arch1-2 #1 SMP PREEMPT_DYNAMIC Wed, 31 Jan 2024 09:22:15 +0000 x86_64 GNU/Linux
  • Browser: N/A

Other information (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, e.g. stackoverflow, gitter, etc.)
Most other servers reject messages containing space before the :, as the standard requires. These include AIOHTTP, Apache httpd, Bun, Daphne, Deno, FastHTTP, Go net/http, Gunicorn, H2O, Hyper, Hypercorn, Jetty, Lighttpd, Mongoose, Nginx, Node.js, LiteSpeed, Passenger, Puma, Tomcat, Unicorn, Uvicorn, Waitress, and WEBrick.

@kenballus
Copy link
Author

I am reporting this in public because reverse proxies are not as lenient as they once were, and I'm not aware of any reverse proxies that still forward spaces at the ends of header values. I imagine that such servers exist, but they are less used than they once were, so I estimate that the risk of this bug is low in the present day.

@webknjaz
Copy link
Member

webknjaz commented Feb 4, 2024

This is likely something to address in Cheroot which is what actually implements HTTP underneath CherryPy.

@webknjaz
Copy link
Member

webknjaz commented Feb 4, 2024

I wonder if resurrecting the abandoned effort of substituting the HTTP parsing with h11 would address this automatically... cherrypy/cheroot#201 / cherrypy/cheroot#262

@kenballus
Copy link
Author

I'll move this issue to Cheroot

@kenballus
Copy link
Author

See cherrypy/cheroot#714

@webknjaz
Copy link
Member

webknjaz commented Jun 7, 2024

FYI I could've just transferred this issue there — just ask next time. I didn't do that initially because there's no reproducer/research verifying this yet.

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

No branches or pull requests

2 participants