Fixing GRPC initial metadata validation#16414
Conversation
|
@htuch for your review |
There was a problem hiding this comment.
I don't think this check is sufficient: absl::ascii_isascii(ch) returns true if ch < 128 (see here: http://docs.ros.org/en/kinetic/api/abseil_cpp/html/ascii_8h_source.html). GRPC spec? (https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md) defines ascii char as one between %x20-%x7E.
There was a problem hiding this comment.
Ok, I can change the check
There was a problem hiding this comment.
If I'm reading the spec right, header names can be lower-case ascii chars, numericals, _, -, and .. validateGrpcHeaderChars will return true if the parameter is an upper-case char (try running python -c 'print("A".isalnum())'. Abseil's kPropertyBits is generated using python script, according to comments in ascii.c. kPropertyBits is then used to verify if a character is an alpha-numeric one),
There was a problem hiding this comment.
So I'm not sure - but according to this: https://github.com/grpc/grpc-go/blob/master/Documentation/grpc-metadata.md#creating-a-new-metadata it sounds like you can define initial metadata to be both lower and upercase but it will be converted to lowercase. If you think it's better to have a stricter check I can do so but I'm not sure it's the correct intent in this case.
There was a problem hiding this comment.
FYI, HTTP/2 always sends header names as lower-case on the wire:
There was a problem hiding this comment.
@markdroth can you also take a look at this? Thanks.
There was a problem hiding this comment.
If I'm understanding this code right, it looks like this is requiring that the metadata be already base64 encoded. I don't think that's necessary for GOOGLE_GRPC, because the gRPC library will automatically do base64 encoding and decoding for header values if the header name ends with "-bin".
There was a problem hiding this comment.
What happens if it is already base64 encoded?
There was a problem hiding this comment.
If the gRPC library automatically does encoding/decoding - what check should be done in this case? or is any value allowed?
There was a problem hiding this comment.
We don't check to see if the value is already base64-encoded; we just unconditionally base64-encode it. So it would wind up being double-base64-encoded on the wire.
I think this will actually work, but it does add unnecessary overhead.
There was a problem hiding this comment.
Then we can probably allow any value for -bin. This check was added in #14129 (CC @asraa) because fuzzers were crashing the gRPC library with inputs that looked like https://github.com/envoyproxy/envoy/pull/14129/files#diff-2a20e9888f070730d0412bf9806728cfae9f9f9269747837f68287ff4fcdb5caR1.
There was a problem hiding this comment.
That seems right, any value probably goes for -bin.
Otherwise you would have seen a crash in the grpc library in the test GoogleGrpcIllegalLengthBase64 if you didn't catch with the exception below...
On the PR as a whole, thanks for correcting this check!
|
Updated the code:
I did not modify the lower/upper case of the header key |
There was a problem hiding this comment.
Nit: superfluous blank. If you really want you can use return std::all_of style here, but it's a bit of a wash.
There was a problem hiding this comment.
Nit: you can probably collapse this down to a single if predicate with &&
I think |
|
@dmitri-d I think it's fine to have input being lower/upper mix; it looks like the C++ gRPC library is robust to this as this was also the previous validation. I'd suspect it just gets forced lower case when put on the wire. @omriz this need a merge to fix format concerns (see CI). Otherwise ready to ship. |
|
/retest |
|
Retrying Azure Pipelines: |
According to the GRPC spec https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md The values in the initial metadata can be any valid ASCII character in case of a non binary header type. Signed-off-by: Omri Zohar <omriz@google.com>
|
/retest |
|
Retrying Azure Pipelines: |
According to the GRPC spec https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md The values in the initial metadata can be any valid ASCII character in case of a non binary header type. Risk Level: Low Testing: Unit Tests Docs Changes:N/A Release Notes: Fixing GRPC initial metadata validation for ASCII characters Signed-off-by: Omri Zohar <omriz@google.com>
Commit Message: Fixing GRPC initial metadata validation
Additional Description:
According to the GRPC spec https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md
The values in the initial metadata can be any valid ASCII character in
case of a non binary header type.
Risk Level: Low
Testing: Unit Tests
Docs Changes:N/A
Release Notes: Fixing GRPC initial metadata validation for ASCII characters
Platform Specific Features: None