cheroot
cheroot copied to clipboard
Host header is not validated
❓ I'm submitting a ...
- [X] 🐞 bug report
- [ ] 🐣 feature request
- [ ] ❓ question about the decisions made in the repository
🐞 Describe the bug. What is the current behavior? An invalid host header which does not conform idna is just passed to the underlying wsgi application w/o any validation
❓ What is the motivation / use case for changing the behavior? If the host header contains invalid data, this this data is passed as the HTTP_HOST environment field. It can lead to various issues
💡 To Reproduce Code
from flask import Flask
from cheroot.wsgi import Server
app = Flask(__name__)
server = Server(bind_addr=("localhost", 5001), wsgi_app=app)
server.safe_start()
Now send a request to the server where you set the Host
header field to foobar/..
.
💡 Expected behavior Cheroot declines requests with invalid host header field.
📋 Environment
- Cheroot version: 10.0.0
- Python version: 3.12.0
- OS: Linux
📋 Additional context This was already reported to flask https://github.com/pallets/flask/issues/5392
Thanks! It'd be useful to know if h11 has this problem so we'd know if #201 would address this problem.
@kasium would something like this be a smaller repro?
from cheroot.wsgi import Server, PathInfoDispatcher
Server(bind_addr=("localhost", 5001), wsgi_app=PathInfoDispatcher({})).safe_start()
@webknjaz this does not show the issue for me
@kasium are you saying that it's Flask that crashes when it sees something it doesn't expect?
It could be useful to get a PR with test cases for valid and invalid values of the header.
Yes, flask assumes that the Header was validated before but it's not.
A valid header is something like localhost:1234
, an invalid one foobar/..
@kasium would you mind composing a pull request with an acceptance/regression test for this? It'd be useful to merge it in even without an implementation (marked with xfail).
Sure, let me have a look later this week
@webknjaz to write a test I need to know where a validation would happen. Also the error does only occur if e.g. a wsgi app parses the header later down the stack.
I checked the cheroot code further and I think the best place for such a validation would be HTTPRequest.read_request_headers
. To keep compatibility, the server could accept a new flag which turns validation on. If the header is not valid, it could then answer with 400 (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Host). What do you think?
Just wondering if this would help? https://github.com/cherrypy/cheroot/pull/722