AWS S3 桶权限安全审计 API 实战:boto3 调用链、公共访问风险识别与修复(Anthropic-Cybersecurity-Skills)
S3 桶误配置(公共可读 ACL、通配符桶策略、未开启加密与版本控制)是云上数据泄露的高频根因。本文以 Anthropic-Cybersecurity-Skills 仓库中 auditing-aws-s3-bucket-permissions 技能的 API 参考文档 为主体,系统讲解基于 boto3 S3 Client 的审计 API 调用链,并结合 SKILL.md 中的七步审计工作流与 scripts/agent.py 的源码实现,给出可直接复制运行的检测与修复方案。读完本文,你将掌握用 AWS CLI / boto3 枚举桶、检测 ACL 公共授权、解析通配符桶策略、核查加密与版本控制,并用 IAM Access Analyzer 与 Prowler 补齐自动化审计的能力。
审计前提:权限边界与工具准备
在执行任何 API 调用前,需要先确认凭证与工具链就绪(对应 SKILL.md 的 Prerequisites 一节):
- AWS CLI v2,配置的凭证需具备
s3:GetBucketPolicy、s3:GetBucketAcl、s3:GetBucketPublicAccessBlock、s3:GetEncryptionConfiguration、s3:ListAllMyBuckets等只读审计权限; - Prowler(
pip install prowler),用于执行 CIS AWS Foundations Benchmark 的自动化检查; - S3audit 或同类轻量枚举工具,用于快速发现公共桶;
- 若需跨账号审计,需要 AWS Organizations 的访问权限;
- Python 3.8+ 与 boto3,用于编写自定义审计脚本(仓库中的 scripts/agent.py 即为此类脚本的完整参考实现)。
需要注意审计工具的适用边界:本技能不适用于非 AWS 对象存储(应使用厂商专属工具),不适用于实时监控(应使用 S3 Event Notifications + Lambda),也不适用于访问模式分析(应使用 S3 Access Analyzer 或 CloudTrail S3 数据事件)。
核心 API 全景:审计用 S3 Client 方法速查
API 参考文档 将安全审计最常用的 S3 方法归纳为下表,覆盖「桶枚举 → 访问控制 → 数据保护」的完整检查面:
| Method | Returns |
|---|---|
list_buckets() |
All buckets in account |
get_bucket_acl() |
ACL grants (AllUsers, AuthenticatedUsers) |
get_public_access_block() |
Block public access configuration |
get_bucket_policy() |
Bucket policy JSON (wildcard principals) |
get_bucket_encryption() |
Default encryption algorithm |
get_bucket_versioning() |
Versioning status |
get_bucket_logging() |
Access logging configuration |
get_bucket_location() |
Bucket region |
其中每一项都对应一个可独立验证的安全控制项,下面逐一结合代码展开。
逐方法深度解析:从桶枚举到数据保护核查
1. 枚举账号内全部桶:list_buckets()
审计的第一步是摸清资产面。list_buckets() 返回账号下所有桶的名称与创建时间:
import boto3
s3 = boto3.client("s3")
response = s3.list_buckets()
for bucket in response["Buckets"]:
print(bucket["Name"], bucket["CreationDate"])
在 scripts/agent.py 中,list_all_buckets() 对该方法做了封装:遍历每个桶后额外调用 get_bucket_location() 解析区域,并将 LocationConstraint 为空的情况归一化为 us-east-1,便于后续报告按区域归类。这也是 SKILL.md 工作流 Step 1 中逐桶 get-bucket-location 的 Python 等价实现。
2. 检查 ACL 公共授权:get_bucket_acl()
ACL 是 S3 的遗留访问控制机制,可向 AllUsers、AuthenticatedUsers 等预定义组授予权限,是公共数据泄露的高危来源:
acl = s3.get_bucket_acl(Bucket="my-bucket")
for grant in acl["Grants"]:
print(grant["Grantee"], grant["Permission"])
从源码实现看,check_bucket_acl() 维护了一个高危 URI 名单,遍历 Grants 时仅命中该名单的授权才会被记录,命中即视为 CRITICAL 级别风险(见下文风险分级)。
3. 获取 / 配置 Block Public Access:get_public_access_block() 与 put_public_access_block()
Block Public Access 是覆盖 ACL 与桶策略的「总闸」,即使在单个资源配置了公共访问,只要此处开启即可兜底拦截:
# Check settings
resp = s3.get_public_access_block(Bucket="my-bucket")
config = resp["PublicAccessBlockConfiguration"]
# Enable all blocks
s3.put_public_access_block(
Bucket="my-bucket",
PublicAccessBlockConfiguration={
"BlockPublicAcls": True,
"IgnorePublicAcls": True,
"BlockPublicPolicy": True,
"RestrictPublicBuckets": True,
},
)
四个开关的语义分别为:BlockPublicAcls(阻止 ACL 授予公共权限)、IgnorePublicAcls(忽略所有公共 ACL)、BlockPublicPolicy(阻止带公共主体的桶策略)、RestrictPublicBuckets(仅限 AWS 服务访问公共桶)。值得注意的是,check_public_access_block() 在调用该方法时捕获 ClientError:当桶从未配置过 Public Access Block 时,API 会抛错,此时函数返回 {"configured": False},把「未配置」本身当作一项审计发现而非崩溃。建议在任何环境检查时优先从账号级 s3control get-public-access-block 看起,再逐桶核对桶级配置,两者必须同时开启才安全。
4. 解析桶策略中的通配符主体:get_bucket_policy()
桶策略是 JSON 格式的资源策略,通配符 Principal: "*" 搭配 s3:GetObject 往往是泄露的根源:
import json
policy_str = s3.get_bucket_policy(Bucket="my-bucket")["Policy"]
policy = json.loads(policy_str)
for stmt in policy["Statement"]:
print(stmt["Effect"], stmt["Principal"], stmt["Action"])
check_bucket_policy() 展示了关键的判定逻辑:仅当 principal == "*" 或 principal == {"AWS": "*"} 时判定为通配符主体问题,并同时提取 Effect、Action 与 Condition——无 aws:SourceVpce、aws:SourceIp 等条件的通配符语句风险更高。这里建议对所有 Statement 同时检查 Condition 是否存在,避免误报(例如仅限特定 VPC 的跨账号共享应视为合规)。
5. 校验默认加密:get_bucket_encryption()
S3 的服务器端加密(SSE-S3 / SSE-KMS / SSE-C)应在写入磁盘前施加:
enc = s3.get_bucket_encryption(Bucket="my-bucket")
rules = enc["ServerSideEncryptionConfiguration"]["Rules"]
print(rules[0]["ApplyServerSideEncryptionByDefault"]["SSEAlgorithm"])
源码中的 check_encryption() 会捕获 ClientError 以区分「未配置加密」与「无权限读取」,并将算法名(如 aws:kms、AES256)记录进报告,供合规审计(SOC 2 / PCI DSS / HIPAA)追溯。
6. 检查版本控制:get_bucket_versioning()
版本控制是防误删、抗勒索与取证恢复的基础:
resp = s3.get_bucket_versioning(Bucket="my-bucket")
print(resp.get("Status", "Disabled"))
对应 check_versioning() 使用 resp.get("Status", "Disabled") 处理未开启版本控制时响应中缺失该字段的情况,缺省即视为 Disabled。
必须重点标记的公共授权 URI
API 参考文档 给出了两条必须标记的高危 Grantee URI,它们是 ACL 公共授权的判据核心:
| URI | Risk |
|---|---|
http://acs.amazonaws.com/groups/global/AllUsers |
Public read/write |
http://acs.amazonaws.com/groups/global/AuthenticatedUsers |
Any AWS account |
AllUsers:授予所有互联网用户,等同于公共读/写,风险最高;AuthenticatedUsers:授予任何 AWS 账号(含未授权账号),远超预期信任边界。
这两条 URI 直接出现在 check_bucket_acl() 的 public_uris 名单中,也与 SKILL.md Step 2 中 aws s3api get-bucket-acl 的 JMESPath 过滤表达式一一对应。
从 API 到完整审计工作流:CLI 命令与源码实现双线对照
七步审计工作流(源自 SKILL.md)
Step 1:枚举全部桶与账号级 Block Public Access
# Check account-level S3 Block Public Access settings
aws s3control get-public-access-block \
--account-id $(aws sts get-caller-identity --query Account --output text) \
--output json
# List all buckets with creation dates
aws s3api list-buckets \
--query 'Buckets[*].[Name,CreationDate]' \
--output table
# Get bucket regions for each bucket
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
Step 2:逐桶检查 Public Access Block 与 ACL
# Check per-bucket Block Public Access settings
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"
# Check ACL for public grants
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
Step 3:分析桶策略中的过度授权
# Extract and analyze bucket policies
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
Step 4:核查加密、版本控制与访问日志
# Check encryption and versioning status for all buckets
for bucket in $(aws s3api list-buckets --query 'Buckets[*].Name' --output text); do
echo "=== $bucket ==="
# Encryption configuration
aws s3api get-bucket-encryption --bucket "$bucket" 2>/dev/null \
&& echo " Encryption: ENABLED" \
|| echo " Encryption: DISABLED"
# Versioning status
aws s3api get-bucket-versioning --bucket "$bucket" \
--query 'Status' --output text
# Logging status
aws s3api get-bucket-logging --bucket "$bucket" \
--query 'LoggingEnabled' --output text 2>/dev/null
done
Step 5:运行 Prowler S3 专项检查
# Run Prowler S3-specific checks
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/
# View summary
prowler aws --checks s3 -M csv -o ./prowler-s3-audit/
Step 6:用 IAM Access Analyzer 发现公共与跨账号共享
# List Access Analyzer findings for S3
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
# Create an analyzer if one does not exist
aws accessanalyzer create-analyzer \
--analyzer-name s3-access-audit \
--type ACCOUNT
Step 7:生成审计报告并修复
# Quick remediation: Enable Block Public Access on a bucket
aws s3api put-public-access-block \
--bucket TARGET_BUCKET \
--public-access-block-configuration \
'BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true'
# Enable default encryption with SSE-KMS
aws s3api put-bucket-encryption \
--bucket TARGET_BUCKET \
--server-side-encryption-configuration \
'{"Rules":[{"ApplyServerSideEncryptionByDefault":{"SSEAlgorithm":"aws:kms","KMSMasterKeyID":"alias/aws/s3"},"BucketKeyEnabled":true}]}'
# Enable versioning
aws s3api put-bucket-versioning \
--bucket TARGET_BUCKET \
--versioning-configuration Status=Enabled
源码级支撑:agent.py 的风险分级模型
scripts/agent.py 将上述 API 全部封装为可复用函数,并以 audit_bucket() 聚合单桶检查结果,最终由 classify_risk() 依据优先级输出风险等级:
- CRITICAL:存在公共 ACL 授权(命中
AllUsers/AuthenticatedUsers); - HIGH:桶策略含通配符主体;
- MEDIUM:未启用默认加密,或未配置 Block Public Access;
- LOW:其余情况。
该脚本支持 --profile / --region(默认读取 AWS_PROFILE、AWS_DEFAULT_REGION 环境变量)、--bucket(单桶定向审计)与 --output(JSON 报告路径,默认 s3_audit_report.json),并会汇总 critical / high 计数,可直接作为自定义审计 Agent 的最小可运行骨架。
实战场景:识别包含客户数据的公共可读桶
场景背景:安全工程师收到 Trusted Advisor 关于公共桶的告警,该桶由开发团队为演示创建且从未加固(见 SKILL.md 的 Common Scenarios)。
处置流程:
- 执行
aws s3api get-bucket-acl,发现授予AllUsersREAD权限的授权项; - 执行
get-bucket-policy,发现Principal: "*"且包含s3:GetObject的策略; - 确认桶级与账号级 Block Public Access 均未开启;
- 枚举桶内容评估数据敏感度;
- 立即为该桶开启 Block Public Access;
- 复盘 CloudTrail S3 数据事件,判断是否存在未授权访问;
- 输出包含时间线、数据清单与修复确认的完整报告。
关键陷阱:强制开启 Block Public Access 可能破坏有意对外提供内容的业务(如静态网站托管)。应用限制前务必确认桶的业务用途,并检查是否存在依赖该桶公共访问的 CloudFront 分发或其他服务。对「数据交换伙伴」类场景,优先通过添加 aws:SourceVpce 或 aws:SourceIp 条件来收敛访问范围,而不是简单删除策略。
审计报告输出模板
SKILL.md 给出了可直接沿用的报告格式,涵盖账号级设置、CRITICAL 发现与修复建议、以及覆盖度统计:
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
关键概念速查
| Term | Definition |
|---|---|
| S3 Block Public Access | 账号级与桶级设置,无论单个资源配置如何,都可覆盖 ACL 与策略以防止公共访问 |
| Bucket Policy | 附加在桶上的 JSON 资源策略,定义谁能访问桶以及可执行哪些操作 |
| ACL (Access Control List) | S3 遗留访问控制机制,向 AWS 账号或 AllUsers、AuthenticatedUsers 等预定义组授予权限 |
| IAM Access Analyzer | AWS 托管服务,分析资源策略以识别与外部实体或公众共享的资源 |
| Server-Side Encryption | S3 在写入磁盘前以 SSE-S3、SSE-KMS 或 SSE-C 在对象级别施加的加密 |
| CIS AWS Foundations Benchmark | 互联网安全中心发布的安全最佳实践标准,包含针对 S3 桶配置的具体控制项 |
框架映射与延伸阅读
本技能在 SKILL.md 的 frontmatter 中声明了与 NIST CSF 2.0(PR.IR-01、ID.AM-08、GV.SC-06、DE.CM-01)以及 MITRE ATT&CK(T1530 数据存储目录、T1619 云存储发现、T1078.004 云账号滥用、T1537/T1567.002 数据渗透)的映射关系,完整的框架映射规则可参考仓库的 mappings/README.md。进一步深入时,可继续阅读:
- 完整 API 参考文档:boto3 方法与参数速查;
- 技能定义 SKILL.md:七步工作流、使用时机与边界;
- 审计 Agent 源码:可运行的端到端审计实现,覆盖枚举、ACL、策略、加密、版本控制、日志与风险分级。
关于 get_bucket_logging()、get_bucket_location() 等更多方法的权威参数说明,可查阅 boto3 官方 S3 服务文档;本文所有示例均已在本仓库对应的脚本与技能文档中得到验证,可直接作为日常 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