Fix the audit of who can read a bucket
Your task
An assistant's Terraform for an avatar bucket set all four public-access-block flags to false and allowed s3:GetObject to *, which means anyone on the internet. Those four flags are S3's guards against public access. The team now audits every bucket config for who can read its objects.
An assistant wrote bucket_read_principals(config). It is in the editor. It has a bug. Find it and fix it.
Input and output:
config: the bucket's settings, one string per line, each meant to bekey=value. The list can be empty.- Return who can read objects, as a list of strings with no repeats, sorted in ascending order.
Rules the tests check:
- Split each line at its first
=. Ignore a line with no=, and ignore unknown keys. - The flags are
block_public_acls,block_public_policy,ignore_public_aclsandrestrict_public_buckets. Each starts as true. A line sets its flag to true only when the value is exactlytrue; any other value, such asfalseorTRUE, sets it to false. A later line overrides an earlier one. statement=<effect>|<principal>|<action>is a policy statement. Ignore it unless the value splits on|into exactly 3 parts, the action iss3:GetObjectors3:*, and the principal is not empty. The effect isAlloworDeny; ignore any other effect.acl=<grantee>grants read through the bucket's access list. Ignore an empty grantee.- If any
Denyprincipal is*, return an empty list. - The policy door: an
Allowfor*counts only when bothblock_public_policyandrestrict_public_bucketsare false. Either one being true drops it. Every otherAllowprincipal counts. - The access-list door: a grant to
AllUsersorAuthenticatedUserscounts only when bothblock_public_aclsandignore_public_aclsare false. Every other grantee counts. - Remove any principal that has a
Deny, wherever its read came from.
Examples
bucket_read_principals(config: list[str]) -> list[str]Example 1
Input
bucket_read_principals(["block_public_acls=false", "block_public_policy=false", "ignore_public_acls=false", "restrict_public_buckets=false", "statement=Allow|*|s3:GetObject"])Output
["*"]Example 2
Input
bucket_read_principals(["block_public_acls=true", "block_public_policy=true", "ignore_public_acls=true", "restrict_public_buckets=true", "statement=Allow|cloudfront.amazonaws.com|s3:GetObject"])Output
["cloudfront.amazonaws.com"]Example 3
Input
bucket_read_principals(["statement=Allow|*|s3:GetObject"])Output
[]