fix: Fixes #244, Added destincation bucket ACL check for CopyObject action (#253)

This commit is contained in:
Jon Austin
2023-09-18 11:49:37 -07:00
committed by GitHub
parent 9f0c9badba
commit 1874d3c329
4 changed files with 63 additions and 0 deletions
+17
View File
@@ -1238,6 +1238,7 @@ func (p *Posix) CopyObject(ctx context.Context, input *s3.CopyObjectInput) (*s3.
}
dstBucket := *input.Bucket
dstObject := *input.Key
owner := *input.ExpectedBucketOwner
if fmt.Sprintf("%v/%v", srcBucket, srcObject) == fmt.Sprintf("%v/%v", dstBucket, dstObject) {
return &s3.CopyObjectOutput{}, s3err.GetAPIError(s3err.ErrInvalidCopyDest)
@@ -1259,6 +1260,22 @@ func (p *Posix) CopyObject(ctx context.Context, input *s3.CopyObjectInput) (*s3.
return nil, fmt.Errorf("stat bucket: %w", err)
}
dstBucketACLBytes, err := xattr.Get(dstBucket, aclkey)
if err != nil {
return nil, fmt.Errorf("get dst bucket acl tag: %w", err)
}
var dstBucketACL auth.ACL
err = json.Unmarshal(dstBucketACLBytes, &dstBucketACL)
if err != nil {
return nil, fmt.Errorf("parse dst bucket acl: %w", err)
}
err = auth.VerifyACL(dstBucketACL, dstBucket, owner, types.PermissionWrite, false)
if err != nil {
return nil, err
}
objPath := filepath.Join(srcBucket, srcObject)
f, err := os.Open(objPath)
if errors.Is(err, fs.ErrNotExist) {
+1
View File
@@ -88,6 +88,7 @@ func TestDeleteObjects(s *S3Conf) {
func TestCopyObject(s *S3Conf) {
CopyObject_non_existing_dst_bucket(s)
CopyObject_not_owned_source_bucket(s)
CopyObject_copy_to_itself(s)
CopyObject_success(s)
}
+44
View File
@@ -1676,6 +1676,50 @@ func CopyObject_non_existing_dst_bucket(s *S3Conf) {
})
}
func CopyObject_not_owned_source_bucket(s *S3Conf) {
testName := "CopyObject_not_owned_source_bucket"
actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
srcObj := "my-obj"
err := putObjects(s3client, []string{srcObj}, bucket)
if err != nil {
return err
}
usr := user{
access: "admin1",
secret: "admin1secret",
role: "admin",
}
cfg := *s
cfg.awsID = usr.access
cfg.awsSecret = usr.secret
err = createUsers(s, []user{usr})
if err != nil {
return err
}
dstBucket := getBucketName()
err = setup(&cfg, dstBucket)
if err != nil {
return err
}
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
_, err = s3client.CopyObject(ctx, &s3.CopyObjectInput{
Bucket: &dstBucket,
Key: getPtr("obj-1"),
CopySource: getPtr(fmt.Sprintf("%v/%v", bucket, srcObj)),
})
cancel()
if err := checkApiErr(err, s3err.GetAPIError(s3err.ErrAccessDenied)); err != nil {
return err
}
return nil
})
}
func CopyObject_copy_to_itself(s *S3Conf) {
testName := "CopyObject_copy_to_itself"
actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
+1
View File
@@ -598,6 +598,7 @@ func (c S3ApiController) PutActions(ctx *fiber.Ctx) error {
CopySourceIfNoneMatch: &copySrcIfNoneMatch,
CopySourceIfModifiedSince: &mtime,
CopySourceIfUnmodifiedSince: &umtime,
ExpectedBucketOwner: &access,
})
if err == nil {
return SendXMLResponse(ctx, res, err, &MetaOpts{