-
Notifications
You must be signed in to change notification settings - Fork 29.6k
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
http2: cannot negotiate ALPN besides http/1.1 #26835
Comments
@nodejs/http2 |
Hello, I'm interested in fixing this issue if possible but I'd like to be sure of what is expected: If the client sends a random ALPN like For the information disclosure part, I'm not sure how one would avoid it but maybe I'm missing something. |
@BlackYoup My reading of the code is this:
At the very least, 2. should be more discriminating: allow diff --git a/lib/internal/http2/core.js b/lib/internal/http2/core.js
index a044039960..8be9ca345d 100644
--- a/lib/internal/http2/core.js
+++ b/lib/internal/http2/core.js
@@ -2830,9 +2830,9 @@ function connectionListener(socket) {
debug('Http2Session server: received a connection');
const options = this[kOptions] || {};
- if (socket.alpnProtocol === false || socket.alpnProtocol === 'http/1.1') {
+ if (socket.alpnProtocol !== 'h2') {
// Fallback to HTTP/1.1
- if (options.allowHTTP1 === true) {
+ if (options.allowHTTP1 === true && socket.alpnProtocol === 'http/1.1') {
socket.server[kIncomingMessage] = options.Http1IncomingMessage;
socket.server[kServerResponse] = options.Http1ServerResponse;
return httpConnectionListener.call(this, socket);
The current error message already gives it away and it looks like @addaleax introduced it intentionally in #18986 so I guess there's not much that can be done there. 🤷 |
Yes, that's what I had in mind too
Alright, then I'll just keep it that way. I'll submit a PR tonight, thanks for the insights :) |
After reading the tests, it seems that it is expected behavior to try to downgrade to HTTP1 if the The test that does not set an ALPN does an HTTP1 request is https://github.com/nodejs/node/blob/5835367df4961bb2d71b0700b430b11f9ad32022/test/parallel/test-http2-https-fallback-http-server-options.js So maybe that's more a documentation issue around the behavior of |
Yeah, this is a feature that never really got the love to finish it all the way through. The check needs to be strict, allowing only h1 or h2 to be specified. We can explicitly add support for additional ALPN values later as appropriate. |
@jasnell alright but what about clients that do not set an ALPN and expect the h1 server to respond when the |
Yeah, I was speaking only in terms of if the ALPN is specified. If it is not, then we have to apply some additional heuristic to determine if it is a valid HTTP/1 request. If |
Then it seems to me that's exactly the behavior we have with the current code. I guess we could add the Unless I'm missing something obvious? |
The documentation for
'unknownProtocol'
says this:The logic seems wrong though. It only passes through nothing (no protocol negotiated) or http/1.1, everything else is ignored:
node/lib/internal/http2/core.js
Lines 2614 to 2634 in 11f8024
Caveat: if the check is loosened, care should be taken not to introduce an information leak.
For an attacker it should not be possible to deduce whether the server has
{ allowHTTP1: true }
and an'unknownProtocol'
listener installed by sending messages with the ALPN proto set tohttp/1.1
and e.g.hax/13.37
, and then comparing the responses he gets back.The text was updated successfully, but these errors were encountered: