# Auditing AWS S3 Bucket Permissions

> 使用 AWS CLI、S3audit 和 Prowler，系统性审计 AWS S3 存储桶权限，识别可公开访问的存储桶、 过度宽松的 ACL、错误配置的存储桶策略和缺失的加密设置，以强制执行最小权限数据访问控制。

- Skill: `killvxk/auditing-aws-s3-bucket-permissions` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add killvxk/auditing-aws-s3-bucket-permissions`
- Raw SKILL.md: https://api.skillmd.com/api/skills/killvxk/auditing-aws-s3-bucket-permissions/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- License: Apache-2.0
- Author: killvxk (https://skillmd.com/u/killvxk)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/killvxk/auditing-aws-s3-bucket-permissions

---


# 审计 AWS S3 存储桶权限

## 适用场景

- 对 AWS 环境进行安全评估时，识别公开暴露的数据
- 加入新 AWS 账户时，为存储资源建立安全基线
- 响应来自 AWS Trusted Advisor 或 Security Hub 的潜在 S3 数据暴露告警时
- 合规框架（SOC 2、PCI DSS、HIPAA）要求定期审查数据访问控制时
- 发生泄露或凭据失陷后，需要立即审查所有可访问 S3 资源时

**不适用于**：审计非 AWS 对象存储（使用提供商特定工具）、实时监控（使用带 Lambda 的 S3 Event Notifications）或审计 S3 访问模式（使用 S3 Access Analyzer 或 CloudTrail S3 数据事件）。

## 前置条件

- 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，用于自定义审计脚本

## 工作流程

### 步骤 1：枚举所有 S3 存储桶及账户级别的公开访问阻止设置

首先检查账户级别的 S3 Block Public Access 设置，然后列出所有存储桶及其区域。

```bash
# 检查账户级别的 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
```

### 步骤 2：检查每个存储桶的公开访问阻止和 ACL 配置

遍历所有存储桶，评估各自的公开访问阻止设置和 ACL 授权。

```bash
# 检查每个存储桶的 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 "  未配置 Block Public Access"

  # 检查 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
```

### 步骤 3：分析存储桶策略中的过度宽松访问

审查存储桶策略中的通配符主体、缺少的条件以及允许广泛访问的语句。

```bash
# 提取并分析存储桶策略
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'  警告: {effect} 使用通配符主体')
        print(f'  操作: {stmt.get(\"Action\", \"\")}')
        print(f'  条件: {stmt.get(\"Condition\", \"无\")}')
"
  fi
done
```

### 步骤 4：验证加密和版本控制设置

检查所有存储桶是否启用了服务器端加密，并为数据保护配置了版本控制。

```bash
# 检查所有存储桶的加密和版本控制状态
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 "  加密: 已启用" \
    || echo "  加密: 未启用"

  # 版本控制状态
  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
```

### 步骤 5：运行 Prowler S3 专项检查

执行 Prowler 的 S3 专项检查，与 CIS AWS Foundations Benchmark 对齐。

```bash
# 运行 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/
```

### 步骤 6：使用 IAM Access Analyzer 识别 S3 公开和跨账户发现

利用 IAM Access Analyzer 识别与外部实体或公开共享的存储桶。

```bash
# 列出 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

# 如果不存在分析器则创建一个
aws accessanalyzer create-analyzer \
  --analyzer-name s3-access-audit \
  --type ACCOUNT
```

### 步骤 7：生成审计报告并进行修复

将发现汇编成可操作的报告，并对严重问题进行修复。

```bash
# 快速修复：对存储桶启用 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 启用默认加密
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 | AWS 服务，分析资源策略以识别与外部实体或公众共享的资源 |
| 服务器端加密（Server-Side Encryption） | S3 在将数据写入磁盘前，使用 SSE-S3、SSE-KMS 或 SSE-C 在对象级别应用的加密 |
| CIS AWS Foundations Benchmark | 互联网安全中心（Center for Internet Security）的安全最佳实践标准，包含 S3 存储桶配置的具体控制措施 |

## 工具与系统

- **AWS CLI**：查询 S3 存储桶配置、策略、ACL 和加密设置的主要接口
- **Prowler**：开源安全工具，含 50+ 项 S3 专项检查，与 CIS、PCI DSS 和 HIPAA 控制对齐
- **IAM Access Analyzer**：AWS 原生服务，持续监控授予外部访问的资源策略
- **S3audit**：轻量级工具，用于快速枚举账户内的公开 S3 存储桶
- **ScoutSuite**：多云审计工具，收集 S3 配置数据并生成风险评分 HTML 报告

## 常见场景

### 场景：识别包含客户数据的可公开读取存储桶

**场景背景**：安全工程师收到 Trusted Advisor 关于可公开访问 S3 存储桶的告警。该存储桶由开发团队为演示而创建，从未进行访问限制。

**方法**：
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 分发或其他服务依赖存储桶的公开访问。

## 输出格式

```
S3 存储桶权限审计报告
=====================================
账户: 123456789012 (生产环境)
日期: 2026-02-23
审计员: 安全工程团队
存储桶总数: 47

账户级别设置:
  Block Public Access: 已启用（全部四项设置）

严重发现:
[S3-001] 通过 ACL 的公开读取访问
  存储桶: marketing-assets-prod
  问题: AllUsers 组通过 ACL 获得 READ 权限
  风险: 任何互联网用户均可列出并下载存储桶内容
  数据敏感性: 包含面向客户但非敏感的营销资产
  修复: 移除 AllUsers ACL 授权，启用 Block Public Access

[S3-002] 存储桶策略中的通配符主体
  存储桶: data-exchange-partner
  问题: 策略允许 s3:GetObject，Principal 为 "*" 且无 VPC/IP 条件
  风险: 本为合作伙伴访问设计，但任何知道存储桶名称的人均可访问
  修复: 添加 aws:SourceVpce 或 aws:SourceIp 条件以限制访问

摘要:
  有公开访问的存储桶:           3 / 47
  未加密的存储桶:               5 / 47
  未启用版本控制的存储桶:      12 / 47
  未启用访问日志的存储桶:      18 / 47
  策略过于宽松的存储桶:         7 / 47
```

