-
Notifications
You must be signed in to change notification settings - Fork 867
Description
If one is to use an S3-compatible service (e.g. for integration testing by mocking S3), signed requests are no longer valid as of this commit fbea753, which appears to use a heuristic to detect whether a request is being made to S3.
When using an S3-compatible service the ClientConfig.ServiceUrl
might no longer satisfy the heuristic which appears to check the endpoint host name, and as such the resourcePath
is double encoded and no longer signs correctly.
This is the heuristic:
private const string S3EndpointPattern = @"^(.+\.)?s3[.-]([a-z0-9-]+)\."; |
and its use:
aws-sdk-net/sdk/src/Core/Amazon.Util/AWSSDKUtils.cs
Lines 318 to 324 in fbea753
// S3 is a special case. For S3 skip the pre encode. | |
// For everything else URL pre encode the resource path segments. | |
if (!S3Uri.IsS3Uri(endpoint)) | |
{ | |
encodedSegments = encodedSegments.Select(segment => UrlEncode(segment, true)); | |
pathWasPreEncoded = true; | |
} |
Expected Behavior
When connecting to an S3-compatible service using ClientConfig.ServiceUrl
, all S3 requests including those using characters that are transformed during URL encoding should be correctly signed according the version 4 signature scheme.
The CanonicalizeResourcePath()
function should only single encode requests.
Current Behavior
The S3-compatible service rejects the request that include characters that are transformed during URL encoding.
Consider an attempt to store an object to a content
bucket and object key: Alp?ha/Be%ta /Test&ing
.
CanonicalizeResourcePath()
was called with the following arguments:
endpoint = "http://192.168.99.100:33886/"
resourcePath = "/content/Alp?ha/Be%ta /Test&ing"
detectPreEncode = true
The function logged the following:
Double encoded /content/Alp?ha/Be%ta /Test&ing with endpoint http://192.168.99.100:33886/ for canonicalization: /content/Alp%253Fha/Be%2525ta%2520/Test%2526ing
Possible Solution
-
It appears that the that signing code is invoked from the S3 client code which intrinsically knows only single URL encoding is required. Expose the functionality through the
AWS4Signer
such that all S3 requests are only single encoded. -
If that isn't possible, provide some means for configuration to disable the heuristic and double encoding.
Context
We have some integration tests that ensure our code correctly handles paths sensitive to URL encoding when storing objects in S3. Upon upgrade to AWSSDK.Core 3.3.21.15 and later, this test started to fail.
Your Environment
- AWSSDK.Core version used: 3.3.21.20
- Service assembly and version used: AWSSDK.S3 3.3.18
- Operating System and version: Microsoft Windows 10
- Targeted .NET platform: .NET Core 2.0