1

I'm trying to list all the buckets with some kind of public access in an account.

The question is: is my rationale correct?

  1. I first checked buckets' access block configuration:
filtered_buckets = list(filter(lambda item: not list_in_list(exceptions, item['Name']), buckets))
public_buckets = []
public_acl_indicator = ['http://acs.amazonaws.com/groups/global/AllUsers','http://acs.amazonaws.com/groups/global/AuthenticatedUsers']
permissions_to_check = ['READ', 'WRITE']

def check_bucket_access_block():
    for bucket in filtered_buckets:
        try:
            response = s3client.get_public_access_block(Bucket=bucket['Name'])
            for key, value in response['PublicAccessBlockConfiguration'].items():
                logger.info('Bucket: {}, {}: {}'.format(bucket['Name'], key, value))
                if not response['PublicAccessBlockConfiguration']['BlockPublicAcls'] and not response['PublicAccessBlockConfiguration']['BlockPublicPolicy'] and bucket['Name'] not in public_buckets:
                    public_buckets.append(bucket['Name'])
        except botocore.exceptions.ClientError as e:
            if e.response['Error']['Code'] == 'NoSuchPublicAccessBlockConfiguration':
                logger.info("Bucket: {} has no Public Access Block Configuration".format(bucket['Name']))
            else:
                logger.info("unexpected error: %s" % (e.response))

If any bucket is set to False on both BlockPublicAcls and BlockPublicPolicy, then it IS public. No matter how they configured on Policies and ACLs(correct?).

  1. Then, I proceed to check the buckets' policy status:
 def check_bucket_status():
    try:
        for bucket in filtered_buckets:
            response = s3client.get_bucket_policy_status(Bucket=bucket['Name'])['PolicyStatus']['IsPublic']
            logger.info('Bucket Name: {}, Public: {}'.format(bucket['Name'], response))
            if response == True and bucket['Name'] not in public_buckets:
                public_buckets.append(bucket['Name'])
    except botocore.exceptions.ClientError as e:
        logger.info("unexpected error: %s" % (e.response))

If a bucket returns true for isPublic, then it IS public. No matter the previous function result.

  1. In the last step, I check the buckets ACLs for AllUser and AuthenticadedUsers permissions:
def check_bucket_acl():
    for bucket in filtered_buckets:
        try:
            response = s3client.get_bucket_acl(Bucket=bucket['Name'])
            logger.info('Bucket: {}, ACL: {}'.format(bucket['Name'], response['Grants']))
            for grant in response['Grants']:
                for (key, value) in grant.items():
                    if key == 'Permission' and any(permission in value for permission in permissions_to_check):
                        for (grantee_key, grantee_value) in grant['Grantee'].items():
                            if 'URI' in grantee_key and grant['Grantee']['URI'] in public_acl_indicator:
                                if bucket['Name'] not in public_buckets:
                                    public_buckets.append(bucket['Name'])
        except botocore.exceptions.ClientError as e:
            logger.info("unexpected error: %s" % (e.response))

When I print the full result, it outputs some buckets. All of them were caught in the first step:

check_bucket_access_block()
logger.info('\n')
check_bucket_status()
logger.info('\n')
check_bucket_acl()
logger.info('\n')
logger.info('Public Buckets: {}'.format(public_buckets))

Another question: Is it necessary to check the Objects' ACLs after going through all these steps? If yes, why?

Kaio H. Cunha
  • 211
  • 2
  • 10
  • 1
    It is not a direct answer for the question but you can enable AWS Macie, and this service can list the public buckets as well. – Sándor Bakos Feb 08 '22 at 18:55

1 Answers1

1

If any bucket is set to False on both BlockPublicAcls and BlockPublicPolicy, then it IS public. No matter how they configured on Policies and ACLs(correct?).

No that's not correct at all. It just means that the bucket is allowed to have a public Policy/ACL, it doesn't mean that the bucket actually has a public Policy/ACL.

Mark B
  • 183,023
  • 24
  • 297
  • 295