fix: Ignore AWSAccessKeyId check for SignV2 policy condition (#19673)

This commit is contained in:
jiuker 2024-05-06 18:52:41 +08:00 committed by GitHub
parent a03ca80269
commit 9a9a49aa84
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 27 additions and 14 deletions

View File

@ -210,18 +210,23 @@ func testPostPolicyBucketHandler(obj ObjectLayer, instanceType string, t TestErr
// Test cases for signature-V2. // Test cases for signature-V2.
testCasesV2 := []struct { testCasesV2 := []struct {
expectedStatus int expectedStatus int
accessKey string
secretKey string secretKey string
formData map[string]string
}{ }{
{http.StatusForbidden, "invalidaccesskey", credentials.SecretKey}, {http.StatusForbidden, credentials.SecretKey, map[string]string{"AWSAccessKeyId": "invalidaccesskey"}},
{http.StatusForbidden, credentials.AccessKey, "invalidsecretkey"}, {http.StatusForbidden, "invalidsecretkey", map[string]string{"AWSAccessKeyId": credentials.AccessKey}},
{http.StatusNoContent, credentials.AccessKey, credentials.SecretKey}, {http.StatusNoContent, credentials.SecretKey, map[string]string{"AWSAccessKeyId": credentials.AccessKey}},
{http.StatusForbidden, credentials.SecretKey, map[string]string{"Awsaccesskeyid": "invalidaccesskey"}},
{http.StatusForbidden, "invalidsecretkey", map[string]string{"Awsaccesskeyid": credentials.AccessKey}},
{http.StatusNoContent, credentials.SecretKey, map[string]string{"Awsaccesskeyid": credentials.AccessKey}},
// Forbidden with key not in policy.conditions for signed requests V2.
{http.StatusForbidden, credentials.SecretKey, map[string]string{"Awsaccesskeyid": credentials.AccessKey, "AnotherKey": "AnotherContent"}},
} }
for i, test := range testCasesV2 { for i, test := range testCasesV2 {
// initialize HTTP NewRecorder, this records any mutations to response writer inside the handler. // initialize HTTP NewRecorder, this records any mutations to response writer inside the handler.
rec := httptest.NewRecorder() rec := httptest.NewRecorder()
req, perr := newPostRequestV2("", bucketName, "testobject", test.accessKey, test.secretKey) req, perr := newPostRequestV2("", bucketName, "testobject", test.secretKey, test.formData)
if perr != nil { if perr != nil {
t.Fatalf("Test %d: %s: Failed to create HTTP request for PostPolicyHandler: <ERROR> %v", i+1, instanceType, perr) t.Fatalf("Test %d: %s: Failed to create HTTP request for PostPolicyHandler: <ERROR> %v", i+1, instanceType, perr)
} }
@ -593,7 +598,7 @@ func postPresignSignatureV4(policyBase64 string, t time.Time, secretAccessKey, l
return signature return signature
} }
func newPostRequestV2(endPoint, bucketName, objectName string, accessKey, secretKey string) (*http.Request, error) { func newPostRequestV2(endPoint, bucketName, objectName string, secretKey string, formInputData map[string]string) (*http.Request, error) {
// Expire the request five minutes from now. // Expire the request five minutes from now.
expirationTime := UTCNow().Add(time.Minute * 5) expirationTime := UTCNow().Add(time.Minute * 5)
// Create a new post policy. // Create a new post policy.
@ -605,12 +610,14 @@ func newPostRequestV2(endPoint, bucketName, objectName string, accessKey, secret
signature := calculateSignatureV2(encodedPolicy, secretKey) signature := calculateSignatureV2(encodedPolicy, secretKey)
formData := map[string]string{ formData := map[string]string{
"AWSAccessKeyId": accessKey, "bucket": bucketName,
"bucket": bucketName, "key": objectName + "/${filename}",
"key": objectName + "/${filename}", "policy": encodedPolicy,
"policy": encodedPolicy, "signature": signature,
"signature": signature, }
"X-Amz-Ignore-AWSAccessKeyId": "",
for key, value := range formInputData {
formData[key] = value
} }
// Create the multipart form. // Create the multipart form.

View File

@ -347,10 +347,16 @@ func checkPostPolicy(formValues http.Header, postPolicyForm PostPolicyForm) erro
} }
delete(checkHeader, formCanonicalName) delete(checkHeader, formCanonicalName)
} }
// For SignV2 - Signature field will be ignored // For SignV2 - Signature/AWSAccessKeyId field will be ignored.
// Policy is generated from Signature with other fields, so it should be ignored
if _, ok := formValues[xhttp.AmzSignatureV2]; ok { if _, ok := formValues[xhttp.AmzSignatureV2]; ok {
delete(checkHeader, xhttp.AmzSignatureV2) delete(checkHeader, xhttp.AmzSignatureV2)
for k := range checkHeader {
// case-insensitivity for AWSAccessKeyId
if strings.EqualFold(k, xhttp.AmzAccessKeyID) {
delete(checkHeader, k)
break
}
}
} }
if len(checkHeader) != 0 { if len(checkHeader) != 0 {