From 4e1065e485cf3cb08e0bc0d3c3d21909e21e5125 Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Thu, 12 Feb 2026 13:28:12 -0800 Subject: [PATCH] Fix: preserve request body for STS signature verification (#8324) * Fix: preserve request body for STS signature verification - Save and restore request body in UnifiedPostHandler after ParseForm() - This allows STS handler to verify signatures correctly - Fixes 'invalid AWS signature: 53' error (ErrContentSHA256Mismatch) - ParseForm() consumes the body, so we need to restore it for downstream handlers * Improve error handling in UnifiedPostHandler - Add http.MaxBytesReader to limit body size to 10 MiB (iamRequestBodyLimit) - Add proper error handling for io.ReadAll failures - Log errors when body reading fails - Prevents DoS attacks from oversized request bodies - Addresses code review feedback --- weed/s3api/s3api_server.go | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/weed/s3api/s3api_server.go b/weed/s3api/s3api_server.go index 53d9a95c4..4a3fa4554 100644 --- a/weed/s3api/s3api_server.go +++ b/weed/s3api/s3api_server.go @@ -1,9 +1,11 @@ package s3api import ( + "bytes" "context" "encoding/json" "fmt" + "io" "net" "net/http" "os" @@ -435,11 +437,33 @@ func (s3a *S3ApiServer) UnifiedPostHandler(w http.ResponseWriter, r *http.Reques } // 2. Parse Form to get Action + // Save the body first so we can restore it for STS handler signature verification + var bodyBytes []byte + if r.Body != nil { + // Limit body size to prevent DoS attacks + r.Body = http.MaxBytesReader(w, r.Body, iamRequestBodyLimit) + var err error + bodyBytes, err = io.ReadAll(r.Body) + if err != nil { + glog.Errorf("failed to read request body: %v", err) + s3err.WriteErrorResponse(w, r, s3err.ErrInvalidRequest) + return + } + r.Body.Close() + // Restore body for ParseForm + r.Body = io.NopCloser(bytes.NewBuffer(bodyBytes)) + } + if err := r.ParseForm(); err != nil { s3err.WriteErrorResponse(w, r, s3err.ErrInvalidRequest) return } + // Restore body again for downstream handlers (STS needs it for signature verification) + if bodyBytes != nil { + r.Body = io.NopCloser(bytes.NewBuffer(bodyBytes)) + } + // 3. Dispatch action := r.Form.Get("Action") if strings.HasPrefix(action, "AssumeRole") {