fix: Prioritize explicit deny in bucket policy statements

This commit is contained in:
niksis02
2025-03-01 01:14:12 +04:00
parent 3e7654eebc
commit 30f3fac4e1
3 changed files with 90 additions and 2 deletions

View File

@@ -48,18 +48,19 @@ func (bp *BucketPolicy) Validate(bucket string, iam IAMService) error {
}
func (bp *BucketPolicy) isAllowed(principal string, action Action, resource string) bool {
var isAllowed bool
for _, statement := range bp.Statement {
if statement.findMatch(principal, action, resource) {
switch statement.Effect {
case BucketPolicyAccessTypeAllow:
return true
isAllowed = true
case BucketPolicyAccessTypeDeny:
return false
}
}
}
return false
return isAllowed
}
type BucketPolicyItem struct {

View File

@@ -471,6 +471,7 @@ func TestPutBucketPolicy(s *S3Conf) {
PutBucketPolicy_incorrect_bucket_name(s)
PutBucketPolicy_object_action_on_bucket_resource(s)
PutBucketPolicy_bucket_action_on_object_resource(s)
PutBucketPolicy_explicit_deny(s)
PutBucketPolicy_success(s)
}
@@ -1042,6 +1043,7 @@ func GetIntTests() IntTests {
"PutBucketPolicy_duplicate_resource": PutBucketPolicy_duplicate_resource,
"PutBucketPolicy_incorrect_bucket_name": PutBucketPolicy_incorrect_bucket_name,
"PutBucketPolicy_object_action_on_bucket_resource": PutBucketPolicy_object_action_on_bucket_resource,
"PutBucketPolicy_explicit_deny": PutBucketPolicy_explicit_deny,
"PutBucketPolicy_bucket_action_on_object_resource": PutBucketPolicy_bucket_action_on_object_resource,
"PutBucketPolicy_success": PutBucketPolicy_success,
"GetBucketPolicy_non_existing_bucket": GetBucketPolicy_non_existing_bucket,

View File

@@ -11196,6 +11196,91 @@ func PutBucketPolicy_bucket_action_on_object_resource(s *S3Conf) error {
})
}
func PutBucketPolicy_explicit_deny(s *S3Conf) error {
testName := "PutBucketPolicy_object_action_on_bucket_resource"
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
user2 := user{"grt2", "grt2secret", "user"}
err := createUsers(s, []user{
{"grt1", "grt1secret", "user"},
user2,
})
if err != nil {
return err
}
resource := fmt.Sprintf("arn:aws:s3:::%v", bucket)
resourceWildCard := fmt.Sprintf("%v/*", resource)
resourcePrefix := fmt.Sprintf("%v/someprefix/*", resource)
policy := fmt.Sprintf(`
{
"Statement": [
{
"Action": [
"s3:*"
],
"Effect": "Allow",
"Principal": [
"grt1"
],
"Resource": [
"%v",
"%v"
]
},
{
"Action": [
"s3:*"
],
"Effect": "Allow",
"Principal": [
"grt2"
],
"Resource": [
"%v",
"%v"
]
},
{
"Action": [
"s3:*"
],
"Effect": "Deny",
"Principal": [
"grt2"
],
"Resource": "%v"
}
]
}
`, resourcePrefix, resource, resourceWildCard, resource, resourcePrefix)
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
_, err = s3client.PutBucketPolicy(ctx, &s3.PutBucketPolicyInput{
Bucket: &bucket,
Policy: &policy,
})
cancel()
if err != nil {
return err
}
userClient := getUserS3Client(user2, s)
ctx, cancel = context.WithTimeout(context.Background(), shortTimeout)
_, err = userClient.PutObject(ctx, &s3.PutObjectInput{
Bucket: &bucket,
Key: getPtr("someprefix/hello"),
})
cancel()
if err := checkApiErr(err, s3err.GetAPIError(s3err.ErrAccessDenied)); err != nil {
return err
}
return nil
})
}
func PutBucketPolicy_success(s *S3Conf) error {
testName := "PutBucketPolicy_success"
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {