From 9a9a49aa84915f2ec34a82524a5332fb1f31083c Mon Sep 17 00:00:00 2001 From: jiuker <2818723467@qq.com> Date: Mon, 6 May 2024 18:52:41 +0800 Subject: [PATCH] fix: Ignore AWSAccessKeyId check for SignV2 policy condition (#19673) --- cmd/post-policy_test.go | 31 +++++++++++++++++++------------ cmd/postpolicyform.go | 10 ++++++++-- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/cmd/post-policy_test.go b/cmd/post-policy_test.go index 3c40da023..186249e1c 100644 --- a/cmd/post-policy_test.go +++ b/cmd/post-policy_test.go @@ -210,18 +210,23 @@ func testPostPolicyBucketHandler(obj ObjectLayer, instanceType string, t TestErr // Test cases for signature-V2. testCasesV2 := []struct { expectedStatus int - accessKey string secretKey string + formData map[string]string }{ - {http.StatusForbidden, "invalidaccesskey", credentials.SecretKey}, - {http.StatusForbidden, credentials.AccessKey, "invalidsecretkey"}, - {http.StatusNoContent, credentials.AccessKey, credentials.SecretKey}, + {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}}, + {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 { // initialize HTTP NewRecorder, this records any mutations to response writer inside the handler. rec := httptest.NewRecorder() - req, perr := newPostRequestV2("", bucketName, "testobject", test.accessKey, test.secretKey) + req, perr := newPostRequestV2("", bucketName, "testobject", test.secretKey, test.formData) if perr != nil { t.Fatalf("Test %d: %s: Failed to create HTTP request for PostPolicyHandler: %v", i+1, instanceType, perr) } @@ -593,7 +598,7 @@ func postPresignSignatureV4(policyBase64 string, t time.Time, secretAccessKey, l 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. expirationTime := UTCNow().Add(time.Minute * 5) // Create a new post policy. @@ -605,12 +610,14 @@ func newPostRequestV2(endPoint, bucketName, objectName string, accessKey, secret signature := calculateSignatureV2(encodedPolicy, secretKey) formData := map[string]string{ - "AWSAccessKeyId": accessKey, - "bucket": bucketName, - "key": objectName + "/${filename}", - "policy": encodedPolicy, - "signature": signature, - "X-Amz-Ignore-AWSAccessKeyId": "", + "bucket": bucketName, + "key": objectName + "/${filename}", + "policy": encodedPolicy, + "signature": signature, + } + + for key, value := range formInputData { + formData[key] = value } // Create the multipart form. diff --git a/cmd/postpolicyform.go b/cmd/postpolicyform.go index f03ca22ed..16addbcc5 100644 --- a/cmd/postpolicyform.go +++ b/cmd/postpolicyform.go @@ -347,10 +347,16 @@ func checkPostPolicy(formValues http.Header, postPolicyForm PostPolicyForm) erro } delete(checkHeader, formCanonicalName) } - // For SignV2 - Signature field will be ignored - // Policy is generated from Signature with other fields, so it should be ignored + // For SignV2 - Signature/AWSAccessKeyId field will be ignored. if _, ok := formValues[xhttp.AmzSignatureV2]; ok { 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 {