You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The effects of validating this way are:
1: For header values that contain characters outside of US_ASCII: The invalid character gets replaced by the replacement character �, and after that substituted again for a question mark "?".
2: For header values that contain invalid characters inside of US_ASCII range (e.g: \t or \n): They are kept as they are.
This doesn't align with Go's (stricter) implementation of the validation:
Here, the correct range of character is validated, and requests fail if there are invalid characters (instead of replacing it with �). But the validation only occurs for headers transmitted, (both req and res), not for headers received.
This creates a number of problems:
Servers will receive different values than what the application sent.
A header test-invalid:José sent by a Java client becomes test-invalid:Jos� and finally test-invalid:Jos? before being sent out.
A header test-invalid:José received by a Java server becomes test-invalid:Jos? before reaching the application code.
If a Go server needs to forward headers originated in a Java client, it can lead to requests failing in the Go server. E.g.: test-invalid-2:a\ta will pass validation in Java, be sent to the Go server, and then Go will fail the validation when transmitting it either in the response or in requests to downstreams.
Steps to reproduce the bug
1: Request with header test-invalid:José will be altered to test-invalid:Jos?
2: Header values that contain invalid characters inside of US_ASCII: They are kept as they are.
Edit: minor detail in how encoded.getBytes() works.
The text was updated successfully, but these errors were encountered:
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 allows some invalid characters.
These are the rules for header values:
The current validation 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 validating this way are:
1: For header values that contain characters outside of US_ASCII: The invalid character gets replaced by the replacement character �, and after that substituted again for a question mark "?".
2: For header values that contain invalid characters inside of US_ASCII range (e.g: \t or \n): They are kept as they are.
This doesn't align with Go's (stricter) implementation of the validation:
https://github.com/grpc/grpc-go/blob/a3a8657078983be4c5e9e9e856c757a5de9b3a45/internal/metadata/metadata.go#L106
Here, the correct range of character is validated, and requests fail if there are invalid characters (instead of replacing it with �). But the validation only occurs for headers transmitted, (both req and res), not for headers received.
This creates a number of problems:
test-invalid:José
sent by a Java client becomestest-invalid:Jos�
and finallytest-invalid:Jos?
before being sent out.test-invalid:José
received by a Java server becomestest-invalid:Jos?
before reaching the application code.test-invalid-2:a\ta
will pass validation in Java, be sent to the Go server, and then Go will fail the validation when transmitting it either in the response or in requests to downstreams.Steps to reproduce the bug
1: Request with header
test-invalid:José
will be altered totest-invalid:Jos?
2: Header values that contain invalid characters inside of US_ASCII: They are kept as they are.
Edit: minor detail in how encoded.getBytes() works.
The text was updated successfully, but these errors were encountered: