When using aws:userId with a role's unique ID but without a wildcard, policy.is_internet_accessible() returns True. Change AROAQXXXXXXYYYYYYZZZZ:foo to AROAQXXXXXXYYYYYYZZZZ:* and it returns False for the check.
policy.json
{
"Statement": [
{
"Action": [
"s3:GetInventoryConfiguration",
"s3:GetBucketLocation",
"s3:GetBucketAcl"
],
"Condition": {
"StringLike": {
"aws:userId": "AROAQXXXXXXYYYYYYZZZZ:foo"
}
},
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Resource": "arn:aws:s3:::mybucket"
}
],
"Version": "2012-10-17"
}
bucket_policy_checker.py
import sys
import json
from policyuniverse.policy import Policy
def is_internet_accessible(policy_path):
try:
with open(policy_path, 'r') as f:
policy_json = json.load(f)
policy = Policy(policy_json)
if policy.is_internet_accessible():
print("🚨 This bucket policy allows internet access!")
else:
print("✅ This bucket policy is NOT internet accessible.")
except Exception as e:
print(f"❌ Error processing policy: {e}")
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: python check_bucket_public.py <path_to_policy.json>")
sys.exit(1)
is_internet_accessible(sys.argv[1])
When using
aws:userIdwith a role's unique ID but without a wildcard,policy.is_internet_accessible()returns True. ChangeAROAQXXXXXXYYYYYYZZZZ:footoAROAQXXXXXXYYYYYYZZZZ:*and it returns False for the check.policy.json
{ "Statement": [ { "Action": [ "s3:GetInventoryConfiguration", "s3:GetBucketLocation", "s3:GetBucketAcl" ], "Condition": { "StringLike": { "aws:userId": "AROAQXXXXXXYYYYYYZZZZ:foo" } }, "Effect": "Allow", "Principal": { "AWS": "*" }, "Resource": "arn:aws:s3:::mybucket" } ], "Version": "2012-10-17" }bucket_policy_checker.py