From 575f4b167bc7f64f6160d742dddd9212df1ac4b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A7=E5=8C=97?= <товарищ@gmail.com> Date: Wed, 30 Jun 2021 15:07:20 -0700 Subject: [PATCH] When a file is being uploaded via PUT or POST request with a presigned url and the body is not nil the file is read and then hashed to compare against the X-Amz-Content-Sha256 query parameter. --- weed/s3api/auth_signature_v4.go | 17 +++++++++++++++++ weed/s3api/s3api_object_handlers.go | 1 + 2 files changed, 18 insertions(+) diff --git a/weed/s3api/auth_signature_v4.go b/weed/s3api/auth_signature_v4.go index 0df26e6fc..542bd1788 100644 --- a/weed/s3api/auth_signature_v4.go +++ b/weed/s3api/auth_signature_v4.go @@ -57,6 +57,7 @@ const ( unsignedPayload = "UNSIGNED-PAYLOAD" ) + // Returns SHA256 for calculating canonical-request. func getContentSha256Cksum(r *http.Request) string { var ( @@ -70,6 +71,20 @@ func getContentSha256Cksum(r *http.Request) string { // X-Amz-Content-Sha256, if not set in presigned requests, checksum // will default to 'UNSIGNED-PAYLOAD'. defaultSha256Cksum = unsignedPayload + if (r.Method == "PUT" || r.Method == "POST") && r.Body != nil { + + buf, _ := ioutil.ReadAll(r.Body) + r.Body.Close() + r.Body = ioutil.NopCloser(bytes.NewBuffer(buf)) + + b, _ := ioutil.ReadAll(bytes.NewBuffer(buf)) + hashedPayload := "" + if len(b) != 0 { + bodyHash := sha256.Sum256(b) + hashedPayload = hex.EncodeToString(bodyHash[:]) + } + return hashedPayload + } v, ok = r.URL.Query()["X-Amz-Content-Sha256"] if !ok { v, ok = r.Header["X-Amz-Content-Sha256"] @@ -365,6 +380,7 @@ func (iam *IdentityAccessManagement) doesPresignedSignatureMatch(hashedPayload s } // Construct new query. query := make(url.Values) + if req.URL.Query().Get("X-Amz-Content-Sha256") != "" { query.Set("X-Amz-Content-Sha256", hashedPayload) } @@ -426,6 +442,7 @@ func (iam *IdentityAccessManagement) doesPresignedSignatureMatch(hashedPayload s if req.URL.Query().Get("X-Amz-Credential") != query.Get("X-Amz-Credential") { return nil, s3err.ErrSignatureDoesNotMatch } + // Verify if sha256 payload query is same. if req.URL.Query().Get("X-Amz-Content-Sha256") != "" { if req.URL.Query().Get("X-Amz-Content-Sha256") != query.Get("X-Amz-Content-Sha256") { diff --git a/weed/s3api/s3api_object_handlers.go b/weed/s3api/s3api_object_handlers.go index 845c9a577..26249fb34 100644 --- a/weed/s3api/s3api_object_handlers.go +++ b/weed/s3api/s3api_object_handlers.go @@ -73,6 +73,7 @@ func (s3a *S3ApiServer) PutObjectHandler(w http.ResponseWriter, r *http.Request) _, s3ErrCode = s3a.iam.isReqAuthenticatedV2(r) case authTypePresigned, authTypeSigned: _, s3ErrCode = s3a.iam.reqSignatureV4Verify(r) + dataReader = r.Body } if s3ErrCode != s3err.ErrNone { s3err.WriteErrorResponse(w, s3ErrCode, r)