首页
/ AWS S3 桶权限安全审计 API 实战:boto3 调用链、公共访问风险识别与修复(Anthropic-Cybersecurity-Skills)

AWS S3 桶权限安全审计 API 实战:boto3 调用链、公共访问风险识别与修复(Anthropic-Cybersecurity-Skills)

2026-09-09 19:46:38作者:乔或婵

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:GetBucketPolicys3:GetBucketAcls3:GetBucketPublicAccessBlocks3:GetEncryptionConfigurations3: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 的遗留访问控制机制,可向 AllUsersAuthenticatedUsers 等预定义组授予权限,是公共数据泄露的高危来源:

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": "*"} 时判定为通配符主体问题,并同时提取 EffectActionCondition——无 aws:SourceVpceaws: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:kmsAES256)记录进报告,供合规审计(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_PROFILEAWS_DEFAULT_REGION 环境变量)、--bucket(单桶定向审计)与 --output(JSON 报告路径,默认 s3_audit_report.json),并会汇总 critical / high 计数,可直接作为自定义审计 Agent 的最小可运行骨架。

实战场景:识别包含客户数据的公共可读桶

场景背景:安全工程师收到 Trusted Advisor 关于公共桶的告警,该桶由开发团队为演示创建且从未加固(见 SKILL.md 的 Common Scenarios)。

处置流程

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

关键陷阱:强制开启 Block Public Access 可能破坏有意对外提供内容的业务(如静态网站托管)。应用限制前务必确认桶的业务用途,并检查是否存在依赖该桶公共访问的 CloudFront 分发或其他服务。对「数据交换伙伴」类场景,优先通过添加 aws:SourceVpceaws: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 账号或 AllUsersAuthenticatedUsers 等预定义组授予权限
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-01ID.AM-08GV.SC-06DE.CM-01)以及 MITRE ATT&CK(T1530 数据存储目录、T1619 云存储发现、T1078.004 云账号滥用、T1537/T1567.002 数据渗透)的映射关系,完整的框架映射规则可参考仓库的 mappings/README.md。进一步深入时,可继续阅读:

关于 get_bucket_logging()get_bucket_location() 等更多方法的权威参数说明,可查阅 boto3 官方 S3 服务文档;本文所有示例均已在本仓库对应的脚本与技能文档中得到验证,可直接作为日常 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