From ab38d6b8f675d5850a634475ff08082096e97a27 Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Wed, 7 Oct 2026 05:19:50 -0700 Subject: [PATCH] s3api: reject unrouted subresources on the DELETE bucket catch-all PutBucketHandler gained the same guard when the route-level check moved into the handlers; DeleteBucketHandler was missed, so an authorized DELETE /bucket?logging could delete the bucket instead of answering NotImplemented. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- weed/s3api/s3api_bucket_handlers.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/weed/s3api/s3api_bucket_handlers.go b/weed/s3api/s3api_bucket_handlers.go index 9991d0ba99..a2ec2dfdbc 100644 --- a/weed/s3api/s3api_bucket_handlers.go +++ b/weed/s3api/s3api_bucket_handlers.go @@ -433,6 +433,14 @@ func (s3a *S3ApiServer) DeleteBucketHandler(w http.ResponseWriter, r *http.Reque bucket, _ := s3_constants.GetBucketAndObject(r) glog.V(3).Infof("DeleteBucketHandler %s", bucket) + + // Same as PutBucketHandler: a query key no DELETE route claimed is an + // unimplemented subresource, not a bare DeleteBucket. + if subresource, found := unroutedSubresource(r, nil); found { + glog.V(1).Infof("unimplemented bucket DELETE subresource ?%s", subresource) + s3err.WriteErrorResponse(w, r, s3err.ErrNotImplemented) + return + } // The teardown below retries, and a failover walk repeats it once per // filer, so the backoff comes out of one allowance held here. r = r.WithContext(withFilerRetryBudget(r.Context(), filerRetryRequestBudget))