fix(sigv4): use encoded request path for inbound signature verification#176
Open
alukach wants to merge 1 commit into
Open
fix(sigv4): use encoded request path for inbound signature verification#176alukach wants to merge 1 commit into
alukach wants to merge 1 commit into
Conversation
Uploads of keys containing characters the client percent-escapes (e.g. a space -> %20) failed with SignatureDoesNotMatch. SigV4's canonical URI is the percent-encoded path the client signed, but `RequestParts` decodes the path (correct for bucket/key routing) and we were passing that decoded path as the `signing_path`. The server then built its canonical request with a literal space while the client signed `%20`, so the signatures never matched. Recover the raw encoded path from the request URL via `Uri::path()` (which does not decode) and use it as the signing path. Routing keeps the decoded path; outbound signing already re-encodes via `url::Url::parse`, so it was unaffected. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contributor
|
🚀 Latest commit deployed to https://source-data-proxy-pr-176.source-coop.workers.dev
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Problem
Uploading an object whose key contains a character the client percent-escapes — e.g. a space (
foo bar→foo%20bar) — fails with403 SignatureDoesNotMatch:Root cause
SigV4's canonical URI is the percent-encoded path the client signed.
RequestParts::from_web_sysdecodes the request path (correct for bucket/key routing —operation.key()needs the decodedfoo bar), and we were passing that same decoded path as thesigning_path. So the server rebuilt its canonical request with a literal space while the client (aws-sdk-js) signed%20→ signatures never match.The outbound leg was already correct:
build_backend_urlhands the decoded key tourl::Url::parse, which re-encodes the space to%20consistently for both the forwarded request and its signature.Fix
Recover the raw encoded path from the request URL via
http::Uri::path()(which does not decode) and use it as the signing path. Routing/bucket-key parsing keeps the decoded path. Handles all escaped characters, not just spaces; falls back to the decoded path if the URL won't parse.Tests
tests/routing.rspinning thehttpbehavior the fix relies on (Uri::path()preserves%20).clippy/checkpass via the pre-commit hook.foo barupload now succeeds.🤖 Generated with Claude Code