Support for canonicalizing URI properly for AWS SigV4 signer#17137
Support for canonicalizing URI properly for AWS SigV4 signer#17137mattklein123 merged 6 commits intoenvoyproxy:mainfrom
Conversation
|
Hi @Y0Username, welcome and thank you for your contribution. We will try to review your Pull Request as quickly as possible. In the meantime, please take a look at the contribution guidelines if you have not done so already. |
|
If I understand this correctly you now created possibility that Envoy and request signer will "observe" different URL path representations. I do not know this feature well enough to say if this important from security perspective or not. Specifically the signer might think that request goes to service A while Envoy ends up routing request to service B because of the differences in path. |
|
/wait-any |
|
@yanavlasov thanks for looking at it. Yes the signer and Envoy can technically see different path representations due to differences in normalizing and encoding. However, this path representation being created here is being used create a hash. This doc explains how to create and sign requests AWS that are not being made by CLI/SDK. The sigv4 algorithm includes a hash of the request payload as part of the request signature to protect against malicious spoofing of a request by using the credentials from a non-malicious request. So the client and server need to hash the request identically. For various reasons (both practical and historical) this is the algorithm that sigv4 uses. Hence the need for different representation of URL path, if we use Envoy's path representation, requests to AWS will fail with: I can add documentation to clarify this behavior. |
mattklein123
left a comment
There was a problem hiding this comment.
It would be great to not have different URL canonicalizing if we don't need it. Does this follow a standard? Can we use the common code that we already have? cc @htuch @yanavlasov @tonya11en for more details.
/wait-any
There was a problem hiding this comment.
Use StringUtil::CaseInsensitiveCompare
There was a problem hiding this comment.
Used absl::EqualsIgnoreCase
There was a problem hiding this comment.
I would just make all of these all into static constexpr absl::string_view in some places you are having to allocate strings for the chars which is unnecessary.
There was a problem hiding this comment.
couldn't you use absl::EndsWith here?
There was a problem hiding this comment.
StringUtil::CaseInsensitiveCompare
There was a problem hiding this comment.
Used absl::EqualsIgnoreCase
There was a problem hiding this comment.
value.empty() ? EMPTY_STRING : value is redundant. Just pass value
There was a problem hiding this comment.
You should use absl::StrSplit(query_fragment, absl::MaxSplits('=', 1)) instead.
|
Yeah, I would like to understand what is going on with this canonicalization logic and how it relates to other path normalization in Envoy. This seems another opportunity for GOLDPANDA-style fun. |
|
There are a lot of deviations in these AWS utilities from the standard way Envoy does things, cURL/AsyncClient being another example. Adding another one is just making folks uncomfortable, especially since there have been CVEs related to path normalization in the past. This could turn out to be another vector for similar bugs. If you could provide more info on why the common Envoy utilities can't be used, it would help. |
|
To be clear, the canonicalized path here is not used for routing. It is just used for calculating the request hash. The hash calculated on the client should match the hash calculated on the server side, otherwise the request fails. So the client needs to canonicalize the path exactly like the server does. Unfortunately, Envoy canonicalizes the path little differently compared to AWS recommendation. The AWS recommendation is also based on RFC 3986, but with little tweaks that are listed here: https://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html |
|
If the canonicalization is not the same I'm not sure there is much we can do about it unfortunately. @tonya11en can you do the initial review here and then we can do a final pass? /wait-any |
|
Thanks for the AWS spec reference. Looking into it more, I agree that there is nothing we can do with existing Envoy normalizations. You may also suggest that operators enable Envoy's |
|
@Y0Username in the future when updating patches, can you please avoid force-pushing? It makes it so we cannot just see what changed since our last review. |
|
@Y0Username you'll need to add a release note to docs/root/version_history/current.rst |
|
/wait |
- Canonicalizing query string - Canonicalizing path string - Adding tests for canonical path and query Ref: https://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html Issue: envoyproxy#16918 Signed-off-by: Yathish Gangolli <yathishsg@gmail.com>
Signed-off-by: Yathish Gangolli <yathishsg@gmail.com>
Signed-off-by: Yathish Gangolli <yathishsg@gmail.com>
Signed-off-by: Yathish Gangolli <yathishsg@gmail.com>
|
@Y0Username not sure if you saw my earlier message, but can you please refrain from force-pushing commits to your PR branch? It makes it so we can't see the diffs between your various revisions. |
I have stopped amending existing commits. I force push because I rebase on |
tonya11en
left a comment
There was a problem hiding this comment.
I think it's ready for others to sweep through now.
mattklein123
left a comment
There was a problem hiding this comment.
LGTM with small release note comment, thanks.
/wait
|
|
||
| * access log: fix `%UPSTREAM_CLUSTER%` when used in http upstream access logs. Previously, it was always logging as an unset value. | ||
| * cluster: delete pools when they're idle to fix unbounded memory use when using PROXY protocol upstream with tcp_proxy. This behavior can be temporarily reverted by setting the ``envoy.reloadable_features.conn_pool_delete_when_idle`` runtime guard to false. | ||
| * extensions: fix the AWS Request Signer extension to correctly normalize the path and query string to be signed according to AWS' guidelines, so that the hash on the server side matches. See `AWS SigV4 documentaion <https://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html>`_. |
There was a problem hiding this comment.
nit: instead of "extensions" can you make this "aws request signer" or something?
Signed-off-by: Yathish Gangolli <yathishsg@gmail.com>
Signed-off-by: Yathish Gangolli <yathishsg@gmail.com>
…bridge-stream * upstream/main: (32 commits) tls: move ssl connection info into SocketAddressProvider (envoyproxy#17334) conn pool: default enable runtime feature `conn_pool_delete_when_idle` (envoyproxy#17577) api: LEDS api introduction (envoyproxy#17419) kafka: add support for api versions request in mesh-filter (envoyproxy#17475) ext_proc: Implement BUFFERED_PARTIAL processing mode (envoyproxy#17531) tooling: Async/pathlib/mypy cleanups and utils (envoyproxy#17505) xds: restructure CertificateProvider fields (envoyproxy#17201) Refactor OverloadIntegrationTest breaking out a test base, and the fake resource monitors. (envoyproxy#17530) listener: move active connection collection out of active tcp listener (envoyproxy#16947) tools: format checks for backticks (envoyproxy#17566) coverage: set lower limit for common/quic and common (envoyproxy#17573) v2: final source removal (envoyproxy#17565) test: bumping coverage (envoyproxy#17564) quic: enforcing header size and contents (envoyproxy#17520) Support for canonicalizing URI properly for AWS SigV4 signer (envoyproxy#17137) listener: add a stat for transport socket connect timeout (envoyproxy#17458) listener: add listen() error handling (envoyproxy#17427) http: return per route config when direct response is set (envoyproxy#17449) removing most v2 references from source/ (envoyproxy#17415) bug fix: return bootstrap when validating config (envoyproxy#17499) ... Signed-off-by: Garrett Bourg <bourg@squareup.com>
…oxy#17137) - Canonicalizing query string - Canonicalizing path string - Adding tests for canonical path and query Ref: https://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html Issue: envoyproxy#16918 Signed-off-by: Yathish Gangolli <yathishsg@gmail.com>
Support for canonicalizing URI properly for AWS SigV4 signer
Ref: https://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
Issue: #16918
Signed-off-by: Yathish Gangolli yathishsg@gmail.com
Commit Message:
Additional Description:
Risk Level:
Testing:
Docs Changes:
Release Notes:
Platform Specific Features:
[Optional Runtime guard:]
[Optional Fixes #Issue]
[Optional Deprecated:]
[Optional API Considerations:]