列出具有公共读取权限的 S3 对象(在私有存储桶中)
Posted
技术标签:
【中文标题】列出具有公共读取权限的 S3 对象(在私有存储桶中)【英文标题】:List S3 objects with public read permissions (in private bucket) 【发布时间】:2019-02-08 15:29:46 【问题描述】:我想保护位于 S3 存储桶中的文件,并确保没有共享敏感文件。
我知道有多种方法(在控制台中和使用脚本)来查看哪些存储桶具有公共权限。
但是,即使对象位于私有存储桶中,也可以授予对象匿名读取权限。
很难跟踪/审核公开可读的文件/对象,因为除了浏览 AWS 控制台中的每条路径之外,我看不到任何找到它们的方法。
有没有办法列出存储桶中所有具有匿名(读取)权限的对象?任何方法都可以,包括 AWSCLI、Boto、REST 等。
我考虑尝试使用匿名 AWSCLI 配置文件,但这不允许列出存储桶内容,因此它只能用于单独测试文件。
我想我可以使用 Boto (https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html#objectacl) 创建一个脚本。这是唯一的方法,还是有官方方法,例如 AWSCLI 命令?
【问题讨论】:
旁注:如果您担心文件以这种方式“泄漏”,您可以添加一个 Bucket Policy 拒绝GetObject
您的 AWS 账户中的用户。这将覆盖每个对象的权限。
【参考方案1】:
您所说的是对象 ACL。本着job-to-be-done 的精神,我想指出您可以configure a bucket to deny public object ACLs. 这可能是预防的最佳企业实践之一。 auditing and verifying continuously is described here. 的最佳企业实践之一
更新:如果您有兴趣监控和审计桶级 ACL,take a look at this managed AWS Config solution.
但是,如果您正在寻找使用 aws-cli
(这是该问题的标签)的 bash 脚本/工具,则可以解决问题:
bucket="my-bucket-name"
search_term="AllUsers"
for key in $(aws s3 ls --recursive s3://$bucket/ | awk '$1=$2=$3=""; print $0' | sed 's/^[ \t]*//'); do
acl=$(aws s3api get-object-acl --bucket $bucket --key $key) &&
result_found=$(echo $acl | grep -q $search_term) &&
if $result_found; then
echo $key;
echo $acl;
fi;
done
它的作用如下:
-
递归列出存储桶中的所有对象
遍历这些对象键
询问 S3 该对象的 ACL 是什么
如果该 ACL 包含字符串“AllUsers”(全局 s3 权限组),它将将该 ACL 回显到标准输出。
我将此问题概括为“如果 ACL 包含给定的$search_term
,则在存储桶中回显所有密钥及其 ACL”,因此,如果其他人遇到类似但略有不同的问题,此解决方案仍然会有所帮助,只要他们将$search_term
更改为适合他们问题的东西。
理想情况下(假设你不想要公共对象)如果你运行这个......什么都不应该出现。
请记住,此解决方案无法很好地适用于包含大量物体的大型桶。
【讨论】:
非常有帮助!要添加到此脚本的 1 件重要的事情是 IFS=$'\n' 在文件的开头,因此它还将支持名称中带有空格的对象 将--key $key
替换为 --key=$key
以支持带有前导破折号的文件名【参考方案2】:
这是 Ruby 中的多线程解决方案:
# Gemfile
source 'https://rubygems.org' do
gem 'aws-sdk'
gem 'thread'
end
# find_public_s3_objects.rb
require 'aws-sdk-s3' # v2: require 'aws-sdk'
require 'thread/pool'
BUCKET = ARGV[0] or raise("expected bucket")
s3 = Aws::S3::Resource.new(region: 'us-east-1')
count = 0
pool = Thread.pool 8
mutex = Mutex.new
s3.bucket(BUCKET).objects.each do |object|
pool.process do
grants = object.acl.grants
mutex.synchronize do
count += 1
if count % 100 == 0
$stderr.write "#count..."
end
end
if grants.map |x| x.grantee.uri .any? |x| x =~ /AllUsers/
mutex.synchronize do
puts object.key
end
end
end
end
pool.shutdown
然后你像这样运行它:
bundle exec ruby find_public_s3_objects.rb my-bucket-name
它比上面提供的基于 Bash 的解决方案快得多。
最初来自Faraday's blog。
【讨论】:
【参考方案3】:在下面的帖子中描述了一个解决方案(使用 C#)来获取存储在 S3 中的每个对象的 ACL。
How to check ACL of the each object in stored in S3
【讨论】:
以上是关于列出具有公共读取权限的 S3 对象(在私有存储桶中)的主要内容,如果未能解决你的问题,请参考以下文章
Amazon S3 存储:可以在私有存储桶中列出公用文件夹吗?