-
Notifications
You must be signed in to change notification settings - Fork 10k
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: Android gRPC h2c calls fail with PROTOCOL_ERROR #14745
Comments
We definitely haven't invested a lot in |
FYI, the original issue and sample uses Docker. You don't need to run Kestrel inside Docker to reproduce this. Android calling Kestrel on a local machine will reproduce this. |
The error doesn't look related to h2c, it should behave the same with and without TLS. There should be server logs detailing what we thought the problem was. First impression: The client is starting with stream id 3 instead of 1. That should be valid but it's unusual and may trip some of the validation logic. |
I'll re-test with verbose logs. |
|
|
It seems rather suspicious. Before we point fingers, we should double check the HTTP/2 spec. Every other gRPC server works with the Android gRPC client so we might be doing the wrong thing here. There is this section on |
For my knowledge, is it common to use h2c with android for this scenario? Also, I'm not sure if this is a 3.1 candidate if it's only h2c? |
In development, yes. All gRPC guides and samples use h2c. That's common across all gRPC stacks apart from .NET. |
The client is clearly using the wrong value, they're connecting over http, not https. The real question here is how strict the server should be about that. While we work that out a bug should also be filed against the client. |
That's here: grpc/grpc-java#6202 (comment) |
Given that the scheme is supposed to represent the URL, I lean towards thinking that validating it is the correct behavior. The spec seems unclear on if the Can we see what other servers do in this situation? IIS and maybe one like NGINX? Should be possible to craft the HTTP/2 packets correctly such that we are using h2c but sending |
In HTTP/1.1 the scheme is never presented in the request, it's assumed based on the transport. Crossing your transport results in pretty epic failures though. IIS/Http.Sys doesn't support h2c. We could try the reverse (sending http to https). |
It really feels like this is correct behavior on Kestrel's side. The scheme is incorrect, thus the protocol has been violated.
That's basically what I mean. I know the scheme isn't actually in the protocol, but if an HTTP/1.1 client made a plaintext request when the user requested an |
Our initial triage sense is that we don't plan to take action here. At best we'd be ignoring a malformed HTTP/2 request, which seems bad. |
If there isn't traction on the client bug, we can revisit this decision. It is true that some other servers are not as rigid about the |
Hello from gRPC. We think the scheme should not be validated. As the spec is unclear, validating it may be too risky. Assuming a client talk to a server through a proxy, the client talk to the proxy using https, and the proxy talk to the server using plaintext. In this case the scheme can be https, and it is not matching the transport. |
In the case of the proxy, we tell app developers to configure middleware to set the appropriate scheme. If you trust the request is coming from a proxy server, you can pull the original scheme from X-Forwarded-Proto or something like that. If we decide not validate the scheme, we would report the real scheme instead of the invalid one provided by the psuedo-header. |
Is anyone aware of any proxies that use the |
@halter73 I haven't even seen signs of a proxy that supports HTTP/2 yet. Most still seem to tunnel it using the standard HTTPS tunneling. |
I'll re-open to continue considering but it still feels wrong to allow an invalid request like this. The spec is pretty clear that "The ":scheme" pseudo-header field includes the scheme portion of the target URI ([RFC3986], Section 3.1)" and the scheme for an As for proxies, it would also be invalid for a proxy to simply pass through the |
I agree with you that To your response, I have two main arguments for not checking the scheme. First, the We went through some old http work group threads, and found some messages clearly arguing for our side (1 2). I also have to said there are people against our option too. If these are not enough to convince you, I think bring this to ietf for a clarification is a good idea. |
The client URI for h2c is "http", not "https". The proxy discussion is hypothetical at this point, let's focus on the Java library. |
There are real people using gRPC through TCP proxies right now, why do you think it is hypothetical? |
Interesting. When you first mentioned proxies, I was thinking about a layer 7 proxy. I hadn't considered how validation might play with a simple TLS termination proxy. Definitely something to consider. How do these proxies communicate the result of the ALPN handshake? Are they configured to route the connection to a different endpoint based on the negotiated protocol? |
Can anybody give names of specific HTTP/2 proxies they're using that would be worth doing interop testing with? |
At this point, given that the gRPC Java client has been updated to fix this, we're going to close this. If there are use cases that come up for which this validation is a problem, we can reconsider. Right now, this is the only client we've encountered in the wild with this mismatch. |
https://tools.ietf.org/html/rfc8164 outlines a use case where sending an |
Describe the bug
Calling gRPC hosted on Kestrel from an Android device over h2c will fail. The client on Android reports a protocol error.
The original reporter of the issue tested Android calling C-core and it succeeded. Android calling Kestrel with TLS succeeded.
Combination of these three will fail:
Originally reported:
To Reproduce
Steps to reproduce the behavior:
Expected behavior
Call succeeds.
Screenshots
Additional context
.NET Core 3.0 GA
Wireshark log: android-protocol-error-nodocker.zip
The text was updated successfully, but these errors were encountered: