fix: sanitize control bytes in x-amzn-{request,lambda}-context headers#734
Merged
Merged
Conversation
Strip C0 control bytes (< 0x20 except \t) and DEL (0x7F) from the JSON serialized into the x-amzn-request-context and x-amzn-lambda-context headers before constructing HeaderValue. RFC 7230 forbids these bytes in header field values, and the request context echoes the original request path verbatim — so a Lambda Function URL probed by a security scanner with crafted paths (e.g. nuclei) would fail every invocation with InvalidHeaderValue, tripping alarms on otherwise-fine traffic. Fixes #732
fec0158 to
65da5fb
Compare
|
Can we add a test for a parallel assertion for x-amzn-lambda-context, since both call sites changed. And a test for the all-clean fast path (worth covering once the signature is Cow-based). And maybe we can assert that the stripped JSON still deserializes back into the original RequestContext type, not just into serde_json::Value. |
seshubaws
reviewed
May 27, 2026
Helps diagnose mis-configured AWS_LWA_REMOVE_BASE_PATH: only fires when the prefix actually matched (stripped length differs from original), so unmatched requests stay quiet.
- Switch strip_forbidden_header_bytes to Cow<'_, [u8]>: header-safe input (the common case) skips allocation, and the fast path becomes observable in tests via Cow::Borrowed. - New test_strip_forbidden_header_bytes_all_clean asserts the borrowed fast path for clean input. - Existing unit test now asserts Cow::Owned on the stripping branch. - Regression test parses the sanitized x-amzn-request-context back into the typed RequestContext (not just serde_json::Value), and adds a parallel assertion for x-amzn-lambda-context — both call sites now exercise strip_forbidden_header_bytes and round-trip through JSON.
seshubaws
approved these changes
May 27, 2026
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.
Summary
< 0x20except\t) and DEL (0x7F) from the JSON serialized intox-amzn-request-contextandx-amzn-lambda-contextbefore constructingHeaderValue. RFC 7230 forbids these bytes in header field values.ApiGatewayV2event with control bytes (0x04,0x7F,0x18) inrequestContext.http.pathand asserts the forwarded request carries a header-safe, JSON-parseablex-amzn-request-context.Fixes #732.
Why
The reporter's Lambda (behind CloudFront → Function URL) returns 5xx every time
nucleiprobes it with paths like/%04%7F%18;{curl,...};because the adapter copiesrequestContext.http.pathverbatim into a JSON header value.http::HeaderValue::from_bytesthen rejects the bytes and the whole invocation fails — tripping alarms on traffic that is otherwise harmless and well-formed at the HTTP layer.Test plan
cargo test --lib— 23 passed (was 21, +2 new)cargo clippy --lib --tests -- -D warningscleanInvalidHeaderValue, then restored it and confirmed it passes