mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-10-13 17:48:29 +02:00
* s3: answer GetBucketReplication, GetBucketWebsite and GetBucketNotificationConfiguration None of the three had a route, so they reached the unconstrained ListObjectsV1 catch-all and a client asking for a bucket's replication config got 200 and a <ListBucketResult> back. Replication and website report their configuration as absent the way AWS does; notification returns the empty configuration AWS returns for a bucket with no events wired up. * s3: stop an unrouted bucket subresource from being answered with a listing ListObjectsV1 is the catch-all GET on a bucket, so every subresource without a route of its own - ?torrent today, whatever AWS adds next - came back 200 with a <ListBucketResult>. A client that asked for a configuration and got a listing either fails its XML decode in a way that reads like corruption, or worse, tolerantly parses it. Refuse the request instead. The allow-list is the ListObjects parameters rather than the subresources, so a new one fails closed. Presigned URLs sign their credentials into the query string, so X-Amz-* and the SigV2 trio have to stay listable.
35 lines
1.2 KiB
Go
35 lines
1.2 KiB
Go
package s3api
|
|
|
|
import (
|
|
"net/http"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
// TestUnroutedBucketSubresource guards the rule that keeps a bucket GET carrying an
|
|
// unimplemented subresource from being answered with a bucket listing: everything
|
|
// SeaweedFS implements is matched by its own route before the ListObjects catch-all,
|
|
// so anything left over that is not a listing parameter is a subresource.
|
|
func TestUnroutedBucketSubresource(t *testing.T) {
|
|
for _, query := range []string{
|
|
"",
|
|
"prefix=a&max-keys=10",
|
|
"list-type=2&continuation-token=x",
|
|
"delimiter=/&encoding-type=url",
|
|
"x-id=ListObjectsV2",
|
|
"prefix=a&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Signature=deadbeef&X-Amz-Expires=900",
|
|
"AWSAccessKeyId=key&Signature=sig&Expires=1700000000",
|
|
} {
|
|
req, _ := http.NewRequest("GET", "http://localhost/bucket?"+query, nil)
|
|
name, found := unroutedBucketSubresource(req)
|
|
assert.False(t, found, "%q is a listing request, got %q", query, name)
|
|
}
|
|
|
|
for _, query := range []string{"torrent=", "replication=", "prefix=a&torrent="} {
|
|
req, _ := http.NewRequest("GET", "http://localhost/bucket?"+query, nil)
|
|
_, found := unroutedBucketSubresource(req)
|
|
assert.True(t, found, "%q should be reported as a subresource", query)
|
|
}
|
|
}
|