gunicorn
gunicorn copied to clipboard
Parsing issue of the CONNECT method
Version bacbf8a
Platform Ubuntu 11.4.0-1ubuntu1~22.04
Description
Hello, I may have found a bug in gunicorn's parsing of CONNECT requests.
RFC 9110 says this:
A server MUST reject a
CONNECTrequest that targets an empty or invalid port number, typically by responding with a400 (Bad Request)status code.
However, gunicorn does not reject such CONNECT request, and does not establish a proxy connection. It handles CONNECT requests just like GET or POST, and responses with 200 OK.
For example:
CONNECT victim.com HTTP/1.1\r\n
Host: victim.com\r\n
\r\n
$ echo -ne "CONNECT victim.com HTTP/1.1\r\nHost: victim.com\r\n\r\n" | nc 172.18.0.7 80
HTTP/1.1 200 OK
Server: gunicorn
Date: Thu, 20 Mar 2025 10:35:56 GMT
Connection: keep-alive
Content-type: application/json
Content-Length: 129
{"headers":[["SE9TVA==","dmljdGltLmNvbQ=="]],"body":"","version":"SFRUUC8xLjE=","uri":"dmljdGltLmNvbQ==","method":"Q09OTkVDVA=="}
well ensure that your appllication is refusing that connection and return a 400 ? How gunicorn would know it needs to refuse it?
How about special-casing only the (upper-case) "CONNECT" method, unconditionally refusing it with 405 Method Not Allowed regardless of whether we care to implement the authority-form restrictions? Would that rule out any confusion, without breaking anything that should have worked before?
(Gunicorn was always a bit peculiar about what methods to accept, so there may not be much of a backwards-incompatibility concern here.)
@pajod whyw ould you refuse this method ? Shouldn't we pass it to the application and let it decides ?
@benoitc If Gunicorn were to pass this method to the application.. then what would Gunicorn do with that connection, after the application decides to send (or entirely ignorant of the method, sends) 2xx code?
I do not think there is a good answer in the scope of WSGI, so its best to leave this unimplemented - just from now on be explicit about it, to rule out confusing proxies.
Hello.
The RFC clearly states that a server MUST reject a CONNECT request that targets an empty or invalid port number. Even if Gunicorn allows the application to decide whether to reject a CONNECT request, should Gunicorn itself directly reject CONNECT requests with an invalid request target? As my example above, Gunicorn didn't seem to reject "the empty port number".