Stricter partNumber checks (#17270)

Fixes #17269
This commit is contained in:
Klaus Post 2023-05-24 08:00:47 -07:00 committed by GitHub
parent 5677f73794
commit 66156b8230
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 27 additions and 6 deletions

View File

@ -245,10 +245,10 @@ func registerAPIRouter(router *mux.Router) {
router.Methods(http.MethodPut).Path("/{object:.+}"). router.Methods(http.MethodPut).Path("/{object:.+}").
HeadersRegexp(xhttp.AmzCopySource, ".*?(\\/|%2F).*?"). HeadersRegexp(xhttp.AmzCopySource, ".*?(\\/|%2F).*?").
HandlerFunc(collectAPIStats("copyobjectpart", maxClients(gz(httpTraceAll(api.CopyObjectPartHandler))))). HandlerFunc(collectAPIStats("copyobjectpart", maxClients(gz(httpTraceAll(api.CopyObjectPartHandler))))).
Queries("partNumber", "{partNumber:[0-9]+}", "uploadId", "{uploadId:.*}") Queries("partNumber", "{partNumber:.*}", "uploadId", "{uploadId:.*}")
// PutObjectPart // PutObjectPart
router.Methods(http.MethodPut).Path("/{object:.+}").HandlerFunc( router.Methods(http.MethodPut).Path("/{object:.+}").HandlerFunc(
collectAPIStats("putobjectpart", maxClients(gz(httpTraceHdrs(api.PutObjectPartHandler))))).Queries("partNumber", "{partNumber:[0-9]+}", "uploadId", "{uploadId:.*}") collectAPIStats("putobjectpart", maxClients(gz(httpTraceHdrs(api.PutObjectPartHandler))))).Queries("partNumber", "{partNumber:.*}", "uploadId", "{uploadId:.*}")
// ListObjectParts // ListObjectParts
router.Methods(http.MethodGet).Path("/{object:.+}").HandlerFunc( router.Methods(http.MethodGet).Path("/{object:.+}").HandlerFunc(
collectAPIStats("listobjectparts", maxClients(gz(httpTraceAll(api.ListObjectPartsHandler))))).Queries("uploadId", "{uploadId:.*}") collectAPIStats("listobjectparts", maxClients(gz(httpTraceAll(api.ListObjectPartsHandler))))).Queries("uploadId", "{uploadId:.*}")

View File

@ -3693,6 +3693,27 @@ func testAPIPutObjectPartHandler(obj ObjectLayer, instanceType, bucketName strin
expectedAPIError: ErrInvalidAccessKeyID, expectedAPIError: ErrInvalidAccessKeyID,
}, },
// Case where part number is invalid.
9: {
objectName: testObject,
content: "hello",
partNumber: "0",
fault: None,
accessKey: credentials.AccessKey,
secretKey: credentials.SecretKey,
expectedAPIError: ErrInvalidPart,
},
10: {
objectName: testObject,
content: "hello",
partNumber: "-10",
fault: None,
accessKey: credentials.AccessKey,
secretKey: credentials.SecretKey,
expectedAPIError: ErrInvalidPart,
},
} }
reqV2Str := "V2 Signed HTTP request" reqV2Str := "V2 Signed HTTP request"

View File

@ -285,7 +285,7 @@ func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *htt
partIDString := r.Form.Get(xhttp.PartNumber) partIDString := r.Form.Get(xhttp.PartNumber)
partID, err := strconv.Atoi(partIDString) partID, err := strconv.Atoi(partIDString)
if err != nil { if err != nil || partID <= 0 {
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrInvalidPart), r.URL) writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrInvalidPart), r.URL)
return return
} }
@ -615,7 +615,7 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http
partIDString := r.Form.Get(xhttp.PartNumber) partIDString := r.Form.Get(xhttp.PartNumber)
partID, err := strconv.Atoi(partIDString) partID, err := strconv.Atoi(partIDString)
if err != nil { if err != nil || partID <= 0 {
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrInvalidPart), r.URL) writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrInvalidPart), r.URL)
return return
} }

View File

@ -2008,10 +2008,10 @@ func registerBucketLevelFunc(bucket *mux.Router, api objectAPIHandlers, apiFunct
bucket.Methods(http.MethodPost).Path("/{object:.+}").HandlerFunc(api.NewMultipartUploadHandler).Queries("uploads", "") bucket.Methods(http.MethodPost).Path("/{object:.+}").HandlerFunc(api.NewMultipartUploadHandler).Queries("uploads", "")
case "CopyObjectPart": case "CopyObjectPart":
// Register CopyObjectPart handler. // Register CopyObjectPart handler.
bucket.Methods(http.MethodPut).Path("/{object:.+}").HeadersRegexp("X-Amz-Copy-Source", ".*?(\\/|%2F).*?").HandlerFunc(api.CopyObjectPartHandler).Queries("partNumber", "{partNumber:[0-9]+}", "uploadId", "{uploadId:.*}") bucket.Methods(http.MethodPut).Path("/{object:.+}").HeadersRegexp("X-Amz-Copy-Source", ".*?(\\/|%2F).*?").HandlerFunc(api.CopyObjectPartHandler).Queries("partNumber", "{partNumber:.*}", "uploadId", "{uploadId:.*}")
case "PutObjectPart": case "PutObjectPart":
// Register PutObjectPart handler. // Register PutObjectPart handler.
bucket.Methods(http.MethodPut).Path("/{object:.+}").HandlerFunc(api.PutObjectPartHandler).Queries("partNumber", "{partNumber:[0-9]+}", "uploadId", "{uploadId:.*}") bucket.Methods(http.MethodPut).Path("/{object:.+}").HandlerFunc(api.PutObjectPartHandler).Queries("partNumber", "{partNumber:.*}", "uploadId", "{uploadId:.*}")
case "ListObjectParts": case "ListObjectParts":
// Register ListObjectParts handler. // Register ListObjectParts handler.
bucket.Methods(http.MethodGet).Path("/{object:.+}").HandlerFunc(api.ListObjectPartsHandler).Queries("uploadId", "{uploadId:.*}") bucket.Methods(http.MethodGet).Path("/{object:.+}").HandlerFunc(api.ListObjectPartsHandler).Queries("uploadId", "{uploadId:.*}")