Describe the bug
The PHP SDK's SignatureV4 excludes content-type from signed headers by default, while other AWS SDKs (e.g. Python/botocore) and also tools like Postman include it. This makes server-side signature verification impossible when the signing client uses a different SDK.
Regression Issue
Expected Behavior
Cross-SDK signature verification should be possible. A request signed by SDK A should always be verifiable by SDK B, given the same credentials and inputs.
Current Behavior
The PHP SDK's hardcoded blacklist includes content-type, whereas Python (botocore) and Java v1 sign it when present. The SignedHeaders field in the Authorization header declares content-type as signed, but the PHP re-signing silently omits it — producing a different signature.
Reproduction Steps
- Sign a POST request with
content-type: application/json using the Python or js aws sdk — both include content-type in SignedHeaders.
- Attempt to verify the signature server-side by re-signing the same request using the PHP SDK.
- Signatures never match because the PHP SDK silently drops
content-type from the canonical request.
Possible Solution
When re-signing for verification purposes, the signer should respect the SignedHeaders field from the incoming Authorization header and only sign exactly those headers — regardless of the blacklist.
Additional Information/Context
No response
SDK version used
3.373.7
Environment details (Version of PHP (php -v)? OS name and version, etc.)
PHP 8.4.11
Describe the bug
The PHP SDK's
SignatureV4excludescontent-typefrom signed headers by default, while other AWS SDKs (e.g. Python/botocore) and also tools like Postman include it. This makes server-side signature verification impossible when the signing client uses a different SDK.Regression Issue
Expected Behavior
Cross-SDK signature verification should be possible. A request signed by SDK A should always be verifiable by SDK B, given the same credentials and inputs.
Current Behavior
The PHP SDK's hardcoded blacklist includes
content-type, whereas Python (botocore) and Java v1 sign it when present. TheSignedHeadersfield in theAuthorizationheader declarescontent-typeas signed, but the PHP re-signing silently omits it — producing a different signature.Reproduction Steps
content-type: application/jsonusing the Python or js aws sdk — both includecontent-typeinSignedHeaders.content-typefrom the canonical request.Possible Solution
When re-signing for verification purposes, the signer should respect the
SignedHeadersfield from the incomingAuthorizationheader and only sign exactly those headers — regardless of the blacklist.Additional Information/Context
No response
SDK version used
3.373.7
Environment details (Version of PHP (
php -v)? OS name and version, etc.)PHP 8.4.11