Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions commands/s3/bucket/policy_json.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,26 @@ const MaxSetSize = 4096
// carry, sorted for [PolicyAction]'s binary search. The rest of the S3
// permission vocabulary stays out on purpose: a key holding s3:CreateBucket
// or s3:DeleteBucket acts outside the policy that granted it, a key holding a
// policy operation could rewrite the policy that granted it, and every
// principal holds s3:ListAllMyBuckets.
// policy operation could rewrite the policy that granted it, a key that
// rewrites the bucket's configuration (versioning, default object lock,
// tags, encryption) changes it for every principal, and every principal
// holds s3:ListAllMyBuckets. Reading that configuration is a policy action.
var policyActions = sorted([]string{
"s3:AbortMultipartUpload",
"s3:DeleteObject",
"s3:DeleteObjectTagging",
"s3:DeleteObjectVersion",
"s3:GetBucketAcl",
"s3:GetBucketCORS",
"s3:GetBucketLocation",
"s3:GetBucketObjectLockConfiguration",
"s3:GetBucketTagging",
"s3:GetBucketVersioning",
"s3:GetObject",
"s3:GetObjectAttributes",
"s3:GetObjectLegalHold",
"s3:GetObjectRetention",
"s3:GetObjectTagging",
"s3:GetObjectVersion",
"s3:ListBucket",
"s3:ListBucketMultipartUploads",
Expand All @@ -62,6 +73,7 @@ var policyActions = sorted([]string{
"s3:PutObject",
"s3:PutObjectLegalHold",
"s3:PutObjectRetention",
"s3:PutObjectTagging",
})

func sorted(s []string) []string {
Expand All @@ -73,6 +85,12 @@ func sorted(s []string) []string {
// its objects; every other policy action is an object action. The split is
// versitygw's, which evaluates the policy against these ARNs.
var bucketActions = []string{
"s3:GetBucketAcl",
"s3:GetBucketCORS",
"s3:GetBucketLocation",
"s3:GetBucketObjectLockConfiguration",
"s3:GetBucketTagging",
"s3:GetBucketVersioning",
"s3:ListBucket",
"s3:ListBucketMultipartUploads",
"s3:ListBucketVersions",
Expand Down
6 changes: 5 additions & 1 deletion commands/s3/bucket/policy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,9 @@ func TestBucketPolicyUnmarshalJSON(t *testing.T) {
), `statement 1: Resource "arn:aws:s3:::videos" names bucket "videos"`},
{"an object action on the bucket ARN", policyJSON(`{"Effect": "Allow", "Principal": "*", "Action": ["s3:GetObject"], "Resource": "arn:aws:s3:::photos"}`), `Action "s3:GetObject" needs Resource "arn:aws:s3:::photos/*"`},
{"a bucket action on the objects ARN", policyJSON(`{"Effect": "Allow", "Principal": "*", "Action": ["s3:ListBucket"], "Resource": "arn:aws:s3:::photos/*"}`), `Action "s3:ListBucket" needs Resource "arn:aws:s3:::photos"`},
{"a bucket configuration read on the objects ARN", policyJSON(`{"Effect": "Allow", "Principal": "*", "Action": ["s3:GetBucketVersioning"], "Resource": "arn:aws:s3:::photos/*"}`), `Action "s3:GetBucketVersioning" needs Resource "arn:aws:s3:::photos"`},
{"an object tagging action on the bucket ARN", policyJSON(`{"Effect": "Allow", "Principal": "*", "Action": ["s3:PutObjectTagging"], "Resource": "arn:aws:s3:::photos"}`), `Action "s3:PutObjectTagging" needs Resource "arn:aws:s3:::photos/*"`},
{"a bucket configuration write", policyJSON(`{"Effect": "Allow", "Principal": "*", "Action": ["s3:PutBucketVersioning"], "Resource": "arn:aws:s3:::photos"}`), `s3:PutBucketVersioning`},
{"the action wildcard on the objects ARN alone", policyJSON(`{"Effect": "Allow", "Principal": "*", "Action": "s3:*", "Resource": "arn:aws:s3:::photos/*"}`), `Action "s3:*" needs Resource "arn:aws:s3:::photos"`},
{"the action wildcard on the bucket ARN alone", policyJSON(`{"Effect": "Allow", "Principal": "*", "Action": "s3:*", "Resource": "arn:aws:s3:::photos"}`), `Action "s3:*" needs Resource "arn:aws:s3:::photos/*"`},
}
Expand All @@ -233,7 +236,8 @@ func TestPolicyActions(t *testing.T) {
for _, a := range actions {
require.True(t, bucket.PolicyAction(a), a)
}
for _, a := range []string{bucket.PolicyWildcard, "*", "s3:CreateBucket", "s3:DeleteBucket", "s3:ListAllMyBuckets", "s3:PutBucketPolicy"} {
for _, a := range []string{bucket.PolicyWildcard, "*", "s3:CreateBucket", "s3:DeleteBucket", "s3:ListAllMyBuckets", "s3:PutBucketPolicy",
"s3:PutBucketVersioning", "s3:PutBucketObjectLockConfiguration", "s3:PutBucketTagging"} {
require.False(t, bucket.PolicyAction(a), a)
}
}
Expand Down
Loading