【问题标题】:List S3 objects with public read permissions (in private bucket)列出具有公共读取权限的 S3 对象(在私有存储桶中)
【发布时间】: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 账户中的用户。这将覆盖每个对象的权限。

标签: amazon-web-services amazon-s3 aws-cli


【解决方案1】:

您所说的是对象 ACL。本着job-to-be-done 的精神,我想指出您可以configure a bucket to deny public object ACLs. 这可能是预防的最佳企业实践之一。 auditing and verifying continuously is described here. 的最佳企业实践之一

更新:如果您有兴趣监控和审计桶级 ACLtake 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

它的作用如下:

  1. 递归列出存储桶中的所有对象
  2. 遍历这些对象键
  3. 询问 S3 该对象的 ACL 是什么
  4. 如果该 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

    【讨论】:

      猜你喜欢
      • 2019-07-14
      • 2019-06-13
      • 2020-05-20
      • 1970-01-01
      • 1970-01-01
      • 2019-10-30
      • 2019-12-23
      • 2019-01-23
      • 1970-01-01
      相关资源
      最近更新 更多