-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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
Metadata: Header value validation #11679
Comments
…acter the same way grpc-go validates the Metadata. closes grpc#11679
To preserve non-ASCII characters in header value we could Unicode encode them before transmission by the gRPC client so é gets transformed to \u0049 in the string representation, gets transmitted and gets decoded back to Unicode on the gRPC server side, and do this in all languages. The question is whether we want to care about supporting non-ASCII characters. @ejona86 |
gRPC does not support non-ASCII characters in header values, and I don't think this is asking they do. We have no desire to add non-ASCII support directly. Non-ASCII should be handled by the application using an encoding of the application's choice, e.g., percent encoding. HTTP is very irregular about such encoding, and often times is formatting-specific, e.g., Unicode in JSON can use
Independent of the Java behavior, that is clearly a bug in Go. From the spec:
|
That's grpc/grpc-go#5318 We should be dropping the headers on the incoming path, since there's no way to differentiate between headers received from some incoming call and headers originating at the application. Changing that behavior will break people, I'm sure. |
Netty should be preventing |
…acter the same way grpc-go validates the Metadata. closes grpc#11679
Hi, thanks for taking the time to look into this. There were a couple of problem with our test setup so we were getting some erroneous results.
The problems (from our point of view at least) are:
I'm unsure of what is the correct path to move from here. For Java specifically: It should treat all the invalid characters the same way (dropping the header + log message). Go's strategy of failing the request instead of dropping the header makes it easier to debug problems, but introducing that in Java at this point would break people's code so I'm not sure if the trade off is worth it. About accepting and echoing back invalid headers: The specification states that the implementations are allowed to drop the values. This is also non backwards-compatible. But I'd argue that is worth introducing the change.
|
Looking at the history, it seems converting to ASCII is very old (Jan 2015), before our first release 0.7.0 in May 2015. Before that point we used UTF-8. That same commit introduces the skipping behavior of control characters, for sending. That pre-dates the restriction in the gRPC spec (Nov 2015), although there had been related discussions starting in Jul 2015. I'm not immediately finding code that filters out headers in the receiving direction. Only ASCII will be provided to AsciiMarshaller, excepting "�" replacements. It is possible to echo back received non-ASCII (because it is just stored as |
What version of gRPC-Java are you using?
1.41.x, but also observed in master branch
What is your environment?
Linux/MacOs, n/a
What did you expect to see?
Metadata validation is consistent between Java and Go implementations.
What did you see instead?
Java treats differently some invalid characters.
These are the rules for header values:
About rule 1 - ASCII-Value should not have leading or trailing whitespace.
We have not yet tested all the cases but it seems like neither Java nor Go are validating for this. Doesn't seem like there is a strong need to implement this.
About rule 2 - ASCII-Value → 1*( %x20-%x7E ) ; space and printable ASCII
The current metadata object in grpc-java relies on
encoded.getBytes(US_ASCII);
:grpc-java/api/src/main/java/io/grpc/Metadata.java
Lines 981 to 985 in 5081e60
grpc-java/api/src/main/java/io/grpc/Metadata.java
Lines 342 to 353 in 5081e60
The effects of this are that depending on the type of invalid character, the headers have different behaviours:
In grpc-go there is a straight forward validation of all the bytes before sending the request. If the validation fails the request call results in error.
About rule 3 - If accepted, care must be taken to make sure that the application is permitted to echo the value back as metadata.
Java uses the same validation as for request headers:
Go doesn't validate anything in the received headers nor in the response headers, so you are able to send back any header. You are also able to send any new headers that break all the rules in the response ( eg: "invalid-$":"Ĩñvá \t łið" )
Steps to reproduce the bug
Edit: Fixed misunderstanding from our side.
The text was updated successfully, but these errors were encountered: