Last active
August 29, 2015 14:26
-
-
Save kainam00/351ed61fad0a891810c0 to your computer and use it in GitHub Desktop.
Remove Everyone / public permissions from S3 bucket objects
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require 'aws-sdk' | |
require 'yaml' | |
# Check args | |
if ARGV[0].nil? || ARGV[1].nil? | |
puts "Usage: securey-s3-bucket.rb bucket_name path-to-config-file.yml dryrun(optional)" | |
puts " Where the config file is a YAML formatted file with the following data:" | |
puts " access_key_id: xxx" | |
puts " secret_access_key: yyy" | |
puts " region: us-east-1" | |
exit 1 | |
end | |
if ARGV[2] | |
dryrun = true | |
end | |
#### Utility functions #### | |
def secure_object(client, bucket, key, dryrun) | |
resp = client.get_object_acl({ | |
bucket: bucket, | |
key: key, | |
}) | |
changed = false | |
newgrants = Array.new() | |
# Go through all the grants, creating a new grants array without the "Everyone" grant | |
resp.grants.each do | grant | | |
# Check to see if there is an "Everyone" grant in the grants array | |
if grant.grantee.uri == "http://acs.amazonaws.com/groups/global/AllUsers" | |
puts "#{key} has 'Everyone' permissions. Fixing." | |
# Mark as insecure so we can fix below | |
changed = true | |
else | |
# If not, copy the grant to the new grants array to be applied to the object if needed | |
# Set the "type" field to CanonicalUserId or Group manually, since it comes from amazon as "nil" for some reason | |
# Damn you Amazon! | |
if grant.grantee.uri.nil? | |
grant.grantee.type = "CanonicalUser" | |
else | |
grant.grantee.type = "Group" | |
end | |
# Copy | |
newgrants << grant | |
end | |
end | |
# Apply changes if needed | |
if changed == true && dryrun != true | |
puts "Applying new grants to #{key}" | |
resp2 = client.put_object_acl ({ | |
access_control_policy: { | |
grants: newgrants, | |
owner: { | |
display_name: resp.owner.display_name, | |
id: resp.owner.id | |
}, | |
}, | |
bucket: bucket, | |
key: key | |
}) | |
@numfixed = @numfixed+1 | |
return true | |
elsif changed == true && dryrun == true | |
puts "*dryrun* is set, not applying new grants to #{key}!" | |
return true | |
else | |
return true | |
end | |
end | |
# Load config file | |
config = YAML.load(File.read(ARGV[1])) | |
# Create AWS client. Slightly different depending on whether we're using roles or not | |
if config["access_key_id"].nil? | |
# Don't pass credentials, we're using roles given to this box | |
client = Aws::S3::Client.new( | |
region: config["region"], | |
) | |
else | |
client = Aws::S3::Client.new( | |
# Pass credentials | |
region: config["region"], | |
credentials: Aws::Credentials.new(config["access_key_id"], config["secret_access_key"]), | |
) | |
end | |
# Loop through all of the objects in the bucket | |
done = false | |
marker = "" | |
numobjects = 0 | |
@numfixed = 0 | |
while done == false | |
resp = client.list_objects( { | |
bucket: ARGV[0], | |
max_keys: 1000, | |
marker: marker | |
}) | |
if resp.is_truncated == false | |
done = true | |
else | |
marker = resp.contents[resp.contents.count - 1].key | |
end | |
resp.contents.each do | object | | |
numobjects = numobjects+1 | |
secure_object(client, ARGV[0], object.key, dryrun) | |
end | |
puts "Working... Checked #{numobjects} objects. Fixed #{@numfixed}" | |
end | |
puts "Done. Checked #{numobjects} objects. Fixed #{@numfixed}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Simple script that loops through an S3 bucket looking for any objects that have Everyone permissions, and removes them (the permissions, not the objects), while keeping all other permissions intact.
Some relevant documentation here: http://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html
Usage is simple enough:
securey-s3-bucket.rb bucket_name path-to-config-file.yml dryrun(optional)
Where the config file is a YAML formatted file with the following data:
access_key_id: xxx
secret_access_key: yyy
region: us-east-1
The script will output anything it's fixing, otherwise it will stay pretty quiet.