fix(boto3): Fix botocore SigV4 failures caused by post-sign trace propagation - #7050
fix(boto3): Fix botocore SigV4 failures caused by post-sign trace propagation#7050pabloDeputter wants to merge 8 commits into
Conversation
- merge Sentry baggage with existing vendor (e.g. Datadog) baggage in botocore's`before-sign` hook; avoiding post-sign header tampering that invalidates the SigV4 signature. - Skip propagation for presigned requests Fixes: #7031 & PY-2667
Codecov Results 📊✅ 99283 passed | ⏭️ 6494 skipped | Total: 105777 | Pass Rate: 93.86% | Execution Time: 347m 5s 📊 Comparison with Base Branch
➖ Removed Tests (1)View removed tests
All tests are passing successfully. ✅ Patch coverage is 94.81%. Project has 2503 uncovered lines. Files with missing lines (2)
Coverage diff@@ Coverage Diff @@
## main #PR +/-##
==========================================
+ Coverage 89.99% 89.99% —%
==========================================
Files 193 193 —
Lines 24946 25016 +70
Branches 9000 9034 +34
==========================================
+ Hits 22451 22513 +62
- Misses 2495 2503 +8
- Partials 1435 1437 +2Generated by Codecov Action |
| return rv | ||
|
|
||
| def endheaders(self: "HTTPConnection", *args: "Any", **kwargs: "Any") -> "Any": | ||
| trace_headers = getattr(self, "_sentrysdk_trace_headers", ()) |
There was a problem hiding this comment.
Does calling sentry_sdk.get_current_scope().iter_trace_propagation_headers() here instead of in putrequest() work?
It would be best to avoid stashing stuff on the HTTPConnection instance if we can help it.
There was a problem hiding this comment.
Good suggestion :) header generation is moved into endheaders() instead of being stored on the connection.
|
|
||
| value = value.lstrip() | ||
| if not value.startswith((b"AWS4-HMAC-SHA256", b"AWS4-ECDSA-P256-SHA256")): | ||
| return set() |
There was a problem hiding this comment.
SigV4 parser aborts on first non-AWS Authorization header
_aws_sigv4_signed_headers returns an empty set on the first Authorization header that does not start with the expected AWS schemes, so a later valid SigV4 header is never inspected and trace headers can be injected, invalidating the signature.
Evidence
_aws_sigv4_signed_headersiteratesbufferlines looking forAuthorizationheaders.- When it finds an
Authorizationline whose value does not start withAWS4-HMAC-SHA256orAWS4-ECDSA-P256-SHA256, it returnsset()immediately. - Because the loop does not
continue, any valid SigV4 header later inbufferis never parsed. - This causes the downstream
endheaderslogic to see an emptysigned_headersset and inject trace headers that break the AWS signature.
Identified by Warden · find-bugs · UD9-DXE
Description
Summary of issue
baggagewas not included inSignedHeaders. Any later modifications to the value did not invalidate the request.before-signevent. It addsbaggage, ... andx-datadog-*before signing. Any later modifications to the value DO invalidate the request, thus later HTTP-client injection is suppressed to avoid duplicate headers.before-signhandler writes the baggage to the AWS requestbaggagein the SigV4 signaturebaggagevalue403 ForbiddenorSignatureDoesNotMatch.Changes
before-signhandler, so finalbaggageandsentry-tracevalues are created before SigV4 signing.http.clientpropagation is delayed untilendheaders(), when the complete request headers and SigV4SignedHeadersare available. Existingbaggageheader is never mutated after it already was signed.Issues
Resolves: #7031 & PY-2667
Reminders
uv run ruff.feat:,fix:,ref:,meta:)