首页
/ AWS S3 存储桶权限审计实战:基于 AWS CLI、Prowler 与 boto3 的最小权限数据管控指南

AWS S3 存储桶权限审计实战:基于 AWS CLI、Prowler 与 boto3 的最小权限数据管控指南

2026-09-09 19:45:23作者:柯茵沙

本文是一份以 SKILL.md 为核心骨架、结合仓库配套源码展开的 AWS S3 存储桶权限审计技术指南。你将在本文掌握一套完整的实操方法论:用 AWS CLI 枚举账号级与存储桶级的 Block Public Access 配置、识别 ACL 公共授权与通配符 Principal 策略、核查加密与版本控制缺失,再叠加 Prowler 的 CIS 基线检查与 IAM Access Analyzer 的跨账号发现能力,最终输出可执行的审计报告并完成最小权限化修复。文末还结合 scripts/agent.py 的源码实现,深入剖析每个检查点的 boto3 底层调用与风险分级逻辑。

适用场景与使用边界

何时使用该审计流程

  • 对 AWS 环境进行安全评估,识别暴露在公网的数据存储;
  • 新接入 AWS 账号,为存储资源建立安全基线;
  • 收到 AWS Trusted Advisor 或 Security Hub 关于 S3 数据暴露的告警时响应排查;
  • SOC 2、PCI DSS、HIPAA 等合规框架要求周期性审查数据访问控制;
  • 发生泄露或凭据失陷后,需要立即全面复查所有可访问的 S3 资源。

明确的不适用场景

本流程不适用于以下情况:

  • 非 AWS 对象存储的审计(应使用对应云厂商的专用工具);
  • 实时监控需求(应改用 S3 Event Notifications 配合 Lambda 实现);
  • S3 访问模式分析(应使用 S3 Access Analyzer 或 CloudTrail S3 数据事件)。

前置条件与最小权限 IAM 设计

执行完整审计需要准备以下环境与权限:

  • AWS CLI v2,配置的凭据需具备 s3:GetBucketPolicys3:GetBucketAcls3:GetBucketPublicAccessBlocks3:GetEncryptionConfigurations3:ListAllMyBuckets 权限——这些是只读审计所需的最小权限集合,避免审计过程本身引入额外风险;
  • Prowlerpip install prowler),用于自动化 CIS 基准检查;
  • S3audit 或同类枚举工具,用于快速发现公开存储桶;
  • 若需跨账号审计,需具备 AWS Organizations 的访问能力;
  • Python 3.8+ 与 boto3,用于运行自定义审计脚本。

仓库中的 scripts/agent.py 正是围绕这套最小权限模型设计的:它通过 boto3.Session(profile_name=..., region_name=...) 复用本地 AWS 凭据配置(见 get_session 函数),并支持 --profile / --region 命令行参数或 AWS_PROFILE / AWS_DEFAULT_REGION 环境变量注入,确保审计身份可追踪、可轮换。

七步审计工作流

Step 1:枚举全部存储桶与账号级 Block Public Access

先检查账号级的 S3 Block Public Access 设置(该设置可覆盖所有存储桶的资源配置),再列出全部存储桶及其所在区域。

# 检查账号级 S3 Block Public Access 设置
aws s3control get-public-access-block \
  --account-id $(aws sts get-caller-identity --query Account --output text) \
  --output json

# 列出所有存储桶及创建时间
aws s3api list-buckets \
  --query 'Buckets[*].[Name,CreationDate]' \
  --output table

# 获取每个存储桶的区域
for bucket in $(aws s3api list-buckets --query 'Buckets[*].Name' --output text); do
  region=$(aws s3api get-bucket-location --bucket "$bucket" --query 'LocationConstraint' --output text)
  echo "$bucket -> ${region:-us-east-1}"
done

注意最后一个命令中的 ${region:-us-east-1}us-east-1 区域的 get-bucket-location 返回 null,因此需要回退为默认区域,这一细节与 agent.pyregion = loc.get("LocationConstraint") or "us-east-1" 的逻辑完全一致,可视为仓库源码对 CLI 经验的印证。

Step 2:逐个检查存储桶的 Public Access Block 与 ACL 配置

遍历所有存储桶,评估其独立的公共访问拦截配置与 ACL 授权情况:

# 检查每个存储桶的 Block Public Access 设置
for bucket in $(aws s3api list-buckets --query 'Buckets[*].Name' --output text); do
  echo "=== $bucket ==="
  aws s3api get-public-access-block --bucket "$bucket" 2>/dev/null || echo "  No Block Public Access configured"

  # 检查 ACL 中是否存在公共授权
  aws s3api get-bucket-acl --bucket "$bucket" \
    --query 'Grants[?Grantee.URI==`http://acs.amazonaws.com/groups/global/AllUsers` || Grantee.URI==`http://acs.amazonaws.com/groups/global/AuthenticatedUsers`]' \
    --output json
done

这里重点标记两个高风险 Grantee URI(来自 references/api-reference.md 的权威清单):

URI 风险
http://acs.amazonaws.com/groups/global/AllUsers 任何人(含匿名用户)可读/写
http://acs.amazonaws.com/groups/global/AuthenticatedUsers 任意 AWS 账号均可访问

agent.py 中,check_bucket_acl 函数同样维护了这份 URI 黑名单,遍历 acl["Grants"] 并收集命中项及其授权类型(如 READ、WRITE),与上面的 CLI 查询构成双轨验证。

Step 3:分析存储桶策略中的过度授权

审查存储桶策略中的通配符 Principal、缺失 Condition 的语句:

# 提取并分析存储桶策略
for bucket in $(aws s3api list-buckets --query 'Buckets[*].Name' --output text); do
  policy=$(aws s3api get-bucket-policy --bucket "$bucket" --output text 2>/dev/null)
  if [ -n "$policy" ]; then
    echo "=== $bucket policy ==="
    echo "$policy" | python3 -c "
import json, sys
policy = json.load(sys.stdin)
for stmt in policy.get('Statement', []):
    principal = stmt.get('Principal', {})
    effect = stmt.get('Effect', '')
    if principal == '*' or principal == {'AWS': '*'}:
        print(f'  WARNING: {effect} with wildcard principal')
        print(f'  Actions: {stmt.get(\"Action\", \"\")}')
        print(f'  Condition: {stmt.get(\"Condition\", \"NONE\")}')
"
  fi
done

该内联 Python 脚本的判定条件(principal == '*' or principal == {'AWS': '*'})在 agent.pycheck_bucket_policy 中得到了逐行复现:命中通配符 Principal 的语句会被记录其 EffectActionCondition,并归入 wildcard_issues 列表——有通配符 Principal 但无 Condition 约束的策略,是"策略允许了不该允许的人"这一问题的最大来源

Step 4:核验加密、版本控制与访问日志

确保所有存储桶启用了服务端加密并配置了版本控制,同时检查访问日志:

# 检查所有存储桶的加密与版本控制状态
for bucket in $(aws s3api list-buckets --query 'Buckets[*].Name' --output text); do
  echo "=== $bucket ==="

  # 加密配置
  aws s3api get-bucket-encryption --bucket "$bucket" 2>/dev/null \
    && echo "  Encryption: ENABLED" \
    || echo "  Encryption: DISABLED"

  # 版本控制状态
  aws s3api get-bucket-versioning --bucket "$bucket" \
    --query 'Status' --output text

  # 日志状态
  aws s3api get-bucket-logging --bucket "$bucket" \
    --query 'LoggingEnabled' --output text 2>/dev/null
done

仓库的 api-reference.md 给出了对应的 boto3 底层调用:get_bucket_encryption 返回 ServerSideEncryptionConfiguration.Rules[0].ApplyServerSideEncryptionByDefault.SSEAlgorithm(即 SSE-S3 / SSE-KMS / SSE-C 算法标识);get_bucket_versioning 通过 resp.get("Status", "Disabled") 判断是否启用;get_bucket_logging 则通过响应中是否存在 LoggingEnabled 键判断日志是否开启。agent.py 对这三个检查点分别封装了 check_encryptioncheck_versioningcheck_logging 三个函数,并将异常(如 ClientError,对应未配置加密)安全降级为"未启用"。

Step 5:运行 Prowler 的 S3 专项检查

执行 Prowler 中与 CIS AWS Foundations Benchmark 对齐的 S3 检查项:

# 运行 Prowler S3 专项检查
prowler aws \
  --checks s3_bucket_public_access \
           s3_bucket_default_encryption \
           s3_bucket_policy_public_write_access \
           s3_bucket_server_access_logging_enabled \
           s3_bucket_versioning_enabled \
           s3_bucket_acl_prohibited \
  -M json-ocsf \
  -o ./prowler-s3-audit/

# 查看汇总结果
prowler aws --checks s3 -M csv -o ./prowler-s3-audit/

Prowler 提供 50+ 项 S3 专项检查,覆盖 CIS、PCI DSS 与 HIPAA 控制项,这里选用的六个检查分别对应公共访问、默认加密、策略公共写权限、服务端访问日志、版本控制与 ACL 禁用,与前面 CLI 手工检查的维度一一呼应,可作为自动化基线持续运行。

Step 6:借助 IAM Access Analyzer 发现公共与跨账号访问

IAM Access Analyzer 能够分析资源策略,识别对外部实体或公众开放共享的资源:

# 列出 S3 相关的 Access Analyzer 发现结果
aws accessanalyzer list-findings \
  --analyzer-arn $(aws accessanalyzer list-analyzers --query 'analyzers[0].arn' --output text) \
  --filter '{"resourceType": {"eq": ["AWS::S3::Bucket"]}}' \
  --query 'findings[*].[resource,status,condition,principal]' \
  --output table

# 若不存在 analyzer 则创建
aws accessanalyzer create-analyzer \
  --analyzer-name s3-access-audit \
  --type ACCOUNT

这是对 Step 2、Step 3 手工检查的重要补充:Access Analyzer 会持续分析资源策略(含存储桶策略与 ACL),主动发现"共享给了外部实体或公众"的存储桶,尤其擅长捕获跨账号协作场景下的意外开放。

Step 7:生成审计报告并修复关键问题

将发现汇总为可执行的报告,并对严重问题实施修复:

# 快速修复:为存储桶启用 Block Public Access
aws s3api put-public-access-block \
  --bucket TARGET_BUCKET \
  --public-access-block-configuration \
  'BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true'

# 启用 SSE-S3/KMS 默认加密
aws s3api put-bucket-encryption \
  --bucket TARGET_BUCKET \
  --server-side-encryption-configuration \
  '{"Rules":[{"ApplyServerSideEncryptionByDefault":{"SSEAlgorithm":"aws:kms","KMSMasterKeyID":"alias/aws/s3"},"BucketKeyEnabled":true}]}'

# 启用版本控制
aws s3api put-bucket-versioning \
  --bucket TARGET_BUCKET \
  --versioning-configuration Status=Enabled

关键概念速查

术语 定义
S3 Block Public Access 账号级与存储桶级设置,可覆盖 ACL 与策略,无论单个资源配置如何都阻止公共访问
Bucket Policy 附着在存储桶上的 JSON 资源策略,定义谁能访问存储桶及可执行哪些操作
ACL(访问控制列表) 传统 S3 访问控制机制,向 AWS 账号或预定义组(如 AllUsers、AuthenticatedUsers)授予权限
IAM Access Analyzer 分析资源策略,识别向外部实体或公众共享的资源
服务端加密 S3 在将数据写入磁盘前,通过 SSE-S3、SSE-KMS 或 SSE-C 在对象层级实施的加密
CIS AWS Foundations Benchmark 互联网安全中心发布的安全最佳实践标准,包含针对 S3 存储桶配置的专项控制

工具矩阵

  • AWS CLI:查询存储桶配置、策略、ACL 与加密设置的主要接口;
  • Prowler:开源安全工具,提供 50+ 项与 CIS、PCI DSS、HIPAA 对齐的 S3 专项检查;
  • IAM Access Analyzer:AWS 原生服务,持续监控授予外部访问权限的资源策略;
  • S3audit:轻量工具,快速枚举账号内的公共 S3 存储桶;
  • ScoutSuite:多云审计工具,采集 S3 配置数据并生成风险评分的 HTML 报告。

典型场景:识别包含客户数据的公共可读存储桶

背景:安全工程师收到 Trusted Advisor 关于公共可访问 S3 存储桶的告警。该存储桶由开发团队为演示创建,从未加锁。

处置路径

  1. 运行 aws s3api get-bucket-acl,发现存在授予 AllUsersREAD 权限;
  2. 检查 get-bucket-policy,发现策略包含 Principal: "*"s3:GetObject
  3. 确认存储桶级与账号级均未启用 Block Public Access;
  4. 枚举存储桶内容,评估数据敏感度;
  5. 立即为该存储桶启用 Block Public Access;
  6. 审查 CloudTrail S3 数据事件,判断是否已发生未授权访问;
  7. 输出包含时间线、数据清单与修复确认的完整报告。

陷阱提示:启用 Block Public Access 可能破坏有意对外提供内容的应用程序(如静态网站)。应用限制前务必核实存储桶的设计用途,并检查是否存在依赖该存储桶公共访问的 CloudFront 分发或其他服务。

输出格式规范

审计结束应产出结构化报告,建议遵循以下模板:

S3 Bucket Permissions Audit Report
=====================================
Account: 123456789012 (Production)
Date: 2026-02-23
Auditor: Security Engineering Team
Total Buckets: 47

ACCOUNT-LEVEL SETTINGS:
  Block Public Access: ENABLED (all four settings)

CRITICAL FINDINGS:
[S3-001] Public Read Access via ACL
  Bucket: marketing-assets-prod
  Issue: AllUsers group granted READ permission via ACL
  Risk: Any internet user can list and download bucket contents
  Data Sensitivity: Contains customer-facing but non-sensitive marketing assets
  Remediation: Remove AllUsers ACL grant, enable Block Public Access

[S3-002] Wildcard Principal in Bucket Policy
  Bucket: data-exchange-partner
  Issue: Policy allows s3:GetObject with Principal "*" and no VPC/IP condition
  Risk: Intended for partner access but accessible to anyone with the bucket name
  Remediation: Add aws:SourceVpce or aws:SourceIp condition to restrict access

SUMMARY:
  Buckets with public access:           3 / 47
  Buckets without encryption:           5 / 47
  Buckets without versioning:          12 / 47
  Buckets without access logging:      18 / 47
  Buckets with overly broad policies:   7 / 47

用仓库源码实现全自动化审计与风险分级

上述 CLI 手工流程可以完全映射为可重复执行的自动化脚本。scripts/agent.py 给出了完整参考实现,其核心价值在于把"检查"与"分级"解耦:

  • 逐项检查audit_bucket 函数将 check_public_access_blockcheck_bucket_aclcheck_bucket_policycheck_encryptioncheck_versioningcheck_logging 六个检查点的结果聚合为单个存储桶的结构化审计结果;
  • 风险分级classify_risk 函数(agent.py)定义了清晰的分级优先级——命中公共 ACL 授权即为 CRITICAL;存在通配符 Principal 策略为 HIGH;未启用加密或未配置 Public Access Block 为 MEDIUM;否则为 LOW。该分级与 SKILL.md 中的处置优先级(先堵公共访问、再收窄策略、后补加密)保持严格一致;
  • 报告输出:脚本通过 --bucket 支持单桶定向审计,缺省则全账号遍历,最终将账号 ID、审计时间、总量与逐桶明细序列化为 JSON 报告(默认 s3_audit_report.json),可直接对接工单系统或 SIEM。

agent.py 接入定时任务或 CI 流水线,即可把本文的七步审计工作流固化为持续的安全基线扫描,配合 Prowler 的 CIS 检查与 IAM Access Analyzer 的持续分析,形成"手工核查 + 自动化扫描 + 策略分析"三层互补的 S3 最小权限管控体系。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
docsdocs
暂无描述
Markdown
900
5.83 K
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.76 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
860
1.35 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
927
1.85 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.94 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
533
603
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.37 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
396
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.04 K
527