AshwinNHacker/iam-diff-visualizer
GitHub: AshwinNHacker/iam-diff-visualizer
一款 AWS IAM 策略差异分析工具,通过计算有效权限变更来揭示隐藏的权限扩张和提升风险,而非仅展示原始 JSON 差异。
Stars: 0 | Forks: 0
# IAM Policy Diff 可视化工具
**展示两个 AWS IAM policy 之间的*有效权限变更* —— 而不仅仅是 JSON diff。**
[](https://github.com/AshwinNHacker/iam-diff-visualizer/actions/workflows/ci.yml)
[](LICENSE)
[](pyproject.toml)
## 问题所在
对两个 IAM policy 文件运行 `git diff` 只能告诉你*文本*发生了变化。它**无法**告诉你:
- 用 `"Action": "s3:Get*"` 替换明确的两个操作列表,会在不知不觉中授予了 **58 个额外的权限**
- 将 `"Resource": "arn:aws:s3:::my-bucket/*"` 扩大为 `"Resource": "*"`,等于在全账户范围内发放了存储桶列举权限
- 在已有的 `ec2:RunInstances` 授权旁边添加 `iam:PassRole`,等于直接打开了一条众所周知的**权限提升路径**
代码审查人员在审批一个“看起来很小、很合理”的 pull request 时,仅凭原始的 JSON diff 根本无法发现上述任何问题。本工具会计算每个 policy 实际产生的**有效授权集**,对其进行 diff,并标出与安全相关的后果。
## 它的实际作用
1. **解析** IAM policy 文档(基于身份的策略,`Version`/`Statement`,`Action`/`NotAction`,`Resource`/`NotResource`,`Condition`)。
2. **展开每一个通配符**(`s3:Get*`, `iam:*`, `*`)为它所授权的具体 AWS 操作,使用包含 **79 种服务、6,671 个真实 AWS IAM 操作**的目录,该目录直接从官方 `botocore` API 定义(与 AWS CLI 和 SDK 使用相同的来源)中挖掘 —— 参见 [`scripts/build_actions_db.py`](scripts/build_actions_db.py)。
3. **计算有效权限**:对于每一个具体的操作,解决 Allow 与显式 Deny 的冲突(Deny 优先),并标记任何依赖于 `Condition` 的授权,而不是将其视为无条件授权。
4. **对有效集合进行 diff**,而不是对 JSON —— 包括添加 / 删除 / 范围变更 / 效果变更 / 条件变更,并明确指出资源范围的扩大。
5. **针对两种 policy 运行安全风险规则集** —— 高风险的单个操作(`iam:PassRole`, `iam:CreatePolicyVersion`, `iam:AttachUserPolicy`, …)以及已知的多操作**权限提升组合**(`iam:PassRole` + `ec2:RunInstances`, `+ cloudformation:CreateStack`, `+ glue:CreateDevEndpoint`, …),然后报告该变更**引入**了哪些发现,又**解决**了哪些发现。
6. **渲染一个独立的 HTML 报告** —— 深色主题,可搜索,可按服务过滤,零外部依赖(可离线打开,无 CDN 调用) —— 此外还提供供 CI pipeline 使用的机器可读 JSON diff。
## 截图
**摘要 + 结论横幅**

**安全风险分析(新引入 vs 已解决)**

**有效权限 diff 表格**

完整的交互式示例报告(在浏览器中打开):[`docs/sample_report_privesc.html`](docs/sample_report_privesc.html) · [`docs/sample_report_remediation.html`](docs/sample_report_remediation.html)
## 安装
```
git clone https://github.com/AshwinNHacker/iam-diff-visualizer.git
cd iam-diff-visualizer
pip install -e .
```
核心引擎和 CLI 具有**零第三方运行时依赖** —— 仅使用标准库。只有当你想重新生成操作目录时才需要 `botocore`,也只有在你想要使用可选的 Web UI 时才需要 `flask`。
## 用法
### CLI
```
# 生成 HTML 报告
iamdiff compare old_policy.json new_policy.json -o report.html
# 机器可读的 diff,例如用于工具链
iamdiff compare old_policy.json new_policy.json --json
# CI 门控:如果变更引入了新的风险发现,则退出代码为 2
iamdiff compare old_policy.json new_policy.json --fail-on-risk -o report.html
# 单个 policy 的仅风险扫描(不作比较)
iamdiff analyze policy.json --fail-on-risk
```
在内置的示例场景上尝试一下(一个看起来无害,但实际上引入了经典 AWS 权限提升路径的 policy 变更):
```
iamdiff compare examples/policy_v1_baseline.json examples/policy_v2_privesc.json -o report.html
```
```
Wrote report.html
+61 added -1 removed ~1 modified =2 unchanged
⚠ 5 new risk finding(s) introduced — see report.
```
以及修复后的版本,用于查看已解决的风险:
```
iamdiff compare examples/policy_v2_privesc.json examples/policy_v3_remediated.json -o remediation.html
```
### 作为库使用
```
from iamdiff import compare_policies
with open("old.json") as f:
old = f.read()
with open("new.json") as f:
new = f.read()
result = compare_policies(old, new)
print(f"{len(result.added)} added, {len(result.removed)} removed, {len(result.modified)} modified")
for risk in result.introduced_risks:
print(f"[{risk.severity}] {risk.title}")
```
### Web UI(可选)
```
pip install -r webapp/requirements.txt
python3 webapp/app.py
# 打开 http://127.0.0.1:5000
```
粘贴两个 policy,点击比较,即可在浏览器中获得渲染好的相同报告。所有数据都不会离开本地进程。
### 在 CI 中使用(policy 变更门控)
```
- name: Block privilege-escalating IAM changes
run: |
iamdiff compare policies/role.json.old policies/role.json --fail-on-risk -o iam-diff-report.html
- uses: actions/upload-artifact@v4
if: always()
with:
name: iam-diff-report
path: iam-diff-report.html
```
## 操作目录的构建方式
对于绝大多数 AWS 服务,真实的 IAM 操作名称与底层的 API 操作名称完全相同(`s3:GetObject` ↔ S3 的 `GetObject` API 调用)。[`scripts/build_actions_db.py`](scripts/build_actions_db.py) 挖掘了 `botocore` 捆绑的每一个 `service-2.json` 定义 —— AWS CLI 和每个 AWS SDK 都是基于这同一个包生成的 —— 以获取每个服务的操作列表,将 botocore 服务目录映射到其 IAM 操作前缀(例如 `monitoring` → `cloudwatch`),并将结果写入 [`iamdiff/data/actions_db.json`](iamdiff/data/actions_db.json)。一个简短的手动维护列表用于修补少数没有匹配 API 操作的 IAM 专属操作(`iam:PassRole`, `s3:GetObjectVersion`, `sts:TagSession` 等)。
这是一个**有据可查的近似方法**,并不是宣称与 AWS IAM Service Authorization Reference 实现逐字节的完全一致 —— 随时可以使用以下命令重新生成:
```
pip install -r requirements-dev.txt
python3 scripts/build_actions_db.py
```
## 范围说明及本工具无法做到之事的坦诚陈述
真实的 IAM 评估是依赖于请求上下文的(源 IP、是否具有 MFA、session tag、时间等),而且在 AWS 众多资源语法之间进行完整的 ARN 模式交集分析本身就是一个极其深奥的问题。本工具是为 **policy 审查**而构建的,因此它做出了两个经过深思熟虑且有明确文档说明的简化,而不是虚假地宣称能进行与 runtime 准确性一致的模拟:
1. 对于某个操作的显式 `Deny` 始终覆盖对该操作的 `Allow`,无论两个 Statement 之间的确切资源模式重合度如何 —— 这是一种保守做法,且两条 Statement 都会被展示出来,以便人工判断资源范围。
2. 任何带有 `Condition` 的授权都会被保留(而不是静默丢弃),但会被标记为 **⚠ conditioned(有条件)** —— 其在现实世界中的效果取决于本工具不评估的上下文。
目录中不存在的服务/操作的操作模式会被按字面意思处理,并在报告的 **Unresolved action patterns** 下列出,而不是被静默忽略。
完整的推理过程请参见 [`iamdiff/effective_permissions.py`](iamdiff/effective_permissions.py) 中的代码注释。
## 项目布局
```
iamdiff/ Core library + CLI
policy_parser.py IAM JSON → normalized Statement objects
actions_db.py Loads the bundled action catalogue
expander.py Wildcard action expansion
effective_permissions.py Allow/Deny/Condition resolution per action
risk_rules.py Privilege-escalation / high-risk action rules
differ.py Effective-permission diff engine
report.py Self-contained HTML report renderer
cli.py `iamdiff compare` / `iamdiff analyze`
data/actions_db.json 6,671 real AWS IAM actions (see above)
webapp/ Optional Flask paste-and-compare UI
examples/ Sample policies (baseline / privesc / remediated)
scripts/build_actions_db.py Regenerates the action catalogue from botocore
tests/ 45 pytest tests across every module
docs/ Sample rendered reports + README screenshots
.github/workflows/ci.yml Matrix tests (Python 3.9–3.12) + CLI smoke test
```
## 测试
```
pip install -r requirements-dev.txt
pytest -v
```
45 个测试涵盖了 policy 解析/验证、通配符展开(包括完整的 `"*"` 目录和未解析模式的回退处理)、有效权限解析(Deny 优先、NotAction、条件传播)、风险规则集(单个操作、权限提升组合、通配符授权)、端到端 diff 引擎(包括核心主张:两个*文本不同*的 policy 展开后得到的*相同*有效授权 diff 与未发生变更的效果一样),以及用于 CI 门控的 CLI 退出代码。
## 路线图 / 扩展想法
- 在基于身份的 policy 之外,支持 Resource policy(S3 bucket policy、KMS key policy)
- 更深层的 ARN 模式交集分析,而不是目前的保守扩大启发式算法
- 将 SCP (Service Control Policy) 评估作为额外的约束层
- 提供一个 GitHub Action wrapper,实现一行代码集成 CI
欢迎贡献 —— 特别是风险规则集([`risk_rules.py`](iamdiff/risk_rules.py)),它旨在随着新的权限提升技术的发布而不断扩展。
## 许可证
MIT —— 见 [LICENSE](LICENSE)。
标签:AWS, DPI, IAM, Python, 无后门, 权限管理, 模型越狱, 策略分析, 逆向工具