简体   繁体   中英

How can I check if an object in an S3 bucket is public or not in boto3?

I am trying to check if all the objects in a specified bucket are public or not, using the boto3 module in python. I have tried using the client.get_object() and client.list_objects() methods, but I am unable to figure out what exactly I should search for as I am new to boto3 and AWS in general.

Also, since my organization prefers using client over resource , so I'm preferably looking for a way to do it using client .

may be a combination of these to tell the full story for each object

client = boto3.client('s3')
bucket = 'my-bucket'
key = 'my-key'
client.get_object_acl(Bucket=bucket, Key=key)
client.get_bucket_acl(Bucket=bucket)
client.get_bucket_policy(Bucket=bucket)

I think the best way to test if an object is public or not is to make an anonymous request to that object URL.

import boto3
import botocore
import requests

bucket_name = 'example-bucket'
object_key = 'example-key'

config = botocore.client.Config(signature_version=botocore.UNSIGNED)
object_url = boto3.client('s3', config=config).generate_presigned_url('get_object', Params={'Bucket': bucket_name, 'Key': object_key})
resp = requests.get(object_url)
if resp.status_code == 200:
    print('The object is public.')
else:
    print('Nope! The object is private or inaccessible.')

Note: You can use requests.head instead of requests.get to save some data transfer.

This function should do the trick. It gets the ACL and then loops through the Grants looking for AllUsers with READ or FULL_CONTROL permissions.

import boto3

def is_public(key, bucket):
    """Returns true if key has public access.

    Args:
        key (str): key to check
        bucket (str, optional): Bucket name.

    Returns:
        (bool)

    Public object ACL example:
    {
        ...
        "Grants": [
            {
                "Grantee": {
                    "Type": "Group",
                    "URI": "http://acs.amazonaws.com/groups/global/AllUsers",
                },
                "Permission": "READ",
            },
            {
                "Grantee": {
                    "ID": "somecrypticidstring",
                    "Type": "CanonicalUser",
                },
                "Permission": "FULL_CONTROL",
            },
        ],
    }

    Private object ACL example:
    {
        ...
        "Grants": [
            {
                "Grantee": {
                    "ID": "somecrypticidstring",
                    "Type": "CanonicalUser",
                },
                "Permission": "FULL_CONTROL",
            }
        ],
    }
    """
    client = boto3.client(
        "s3",
        aws_access_key_id=YOUR_AWS_ACCESS_KEY_ID,
        aws_secret_access_key=YOUR_AWS_SECRET_ACCESS_KEY,
    )
    d = client.get_object_acl(Bucket=bucket, Key=key)

    try:
        for grant in d["Grants"]:
            if (
                "URI" in grant["Grantee"]
                and grant["Grantee"]["URI"].endswith("AllUsers")
                and grant["Permission"] in ["READ", "FULL_CONTROL"]
            ):
                return True
        return False
    except Exception:
        # Cannot determine if s3 object is public.
        return False

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM