AWS S3 存储桶权限审计实战:基于 AWS CLI、Prowler 与 boto3 的最小权限数据管控指南
本文是一份以 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:GetBucketPolicy、s3:GetBucketAcl、s3:GetBucketPublicAccessBlock、s3:GetEncryptionConfiguration、s3:ListAllMyBuckets权限——这些是只读审计所需的最小权限集合,避免审计过程本身引入额外风险; - Prowler(
pip 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.py 中 region = 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.py 的 check_bucket_policy 中得到了逐行复现:命中通配符 Principal 的语句会被记录其 Effect、Action 与 Condition,并归入 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_encryption、check_versioning、check_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 存储桶的告警。该存储桶由开发团队为演示创建,从未加锁。
处置路径:
- 运行
aws s3api get-bucket-acl,发现存在授予AllUsers的READ权限; - 检查
get-bucket-policy,发现策略包含Principal: "*"与s3:GetObject; - 确认存储桶级与账号级均未启用 Block Public Access;
- 枚举存储桶内容,评估数据敏感度;
- 立即为该存储桶启用 Block Public Access;
- 审查 CloudTrail S3 数据事件,判断是否已发生未授权访问;
- 输出包含时间线、数据清单与修复确认的完整报告。
陷阱提示:启用 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_block、check_bucket_acl、check_bucket_policy、check_encryption、check_versioning、check_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 最小权限管控体系。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust4.2 K634
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown300
jforgamejforgame是一个一站式游戏服务器开发框架。包含游戏服务器开发所需要的各种组件,比如网关,socket服务端与客户端,自定义高效消息编解码,游戏热更新,游戏通用工具等等。包含游戏服,跨服,匹配服,后台管理系统等实现,同时提供大量业务案例以供学习。亦可用于其他socket应用,例如及时聊天等。Java101
fizz-gateway-nodeAn Aggregation API Gateway in Java . FizzGate 是一个基于 Java开发的微服务聚合网关,是拥有自主知识产权的应用网关国产化替代方案,能够实现热服务编排聚合、自动授权选择、线上服务脚本编码、在线测试、高性能路由、API审核管理、回调管理等目的,拥有强大的自定义插件系统可以自行扩展,并且提供友好的图形化配置界面,能够快速帮助企业进行API服务治理、减少中间层胶水代码以及降低编码投入、提高 API 服务的稳定性和安全性。Java60
certd开源SSL证书管理工具;全自动证书申请、更新、续期;通配符证书,泛域名证书申请;证书自动化部署到阿里云、腾讯云、主机、群晖、宝塔;https证书,pfx证书,der证书,TLS证书,nginx证书自动续签自动部署JavaScript60
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python280