| name | testing-for-broken-access-control |
| description | 系统性测试 Web 应用程序中的访问控制缺陷,包括权限提升、缺失的功能级检查以及不安全的直接对象引用。 |
| domain | cybersecurity |
| subdomain | web-application-security |
| tags | ["penetration-testing","access-control","authorization","owasp","privilege-escalation","web-security"] |
| version | 1.0 |
| author | mahipal |
| license | Apache-2.0 |
测试访问控制缺陷(Testing for Broken Access Control)
适用场景
- 在授权渗透测试中,作为 OWASP A01:2021 - 访问控制缺陷的主要评估项目时
- 评估所有应用端点上基于角色的访问控制(RBAC)实现时
- 测试多租户应用中不同组织的用户隔离时
- 评估 API 端点上缺失或不一致的授权检查时
- 在以权限提升和未授权访问为主要关注点的安全审计期间
前置条件
- 授权:针对目标的书面渗透测试协议
- Burp Suite Professional:配合 Authorize 扩展进行自动化访问控制测试
- 多个测试账户:各角色级别的账户(管理员、经理、用户、访客)
- 应用角色矩阵:记录每个角色应/不应访问的内容
- curl/httpie:在不同认证上下文下手工测试端点
- ffuf:发现可能缺少访问控制的隐藏端点
工作流程
步骤 1 — 映射所有端点并创建访问控制矩阵
记录每个端点及各角色的预期访问级别。
ffuf -u "https://target.example.com/FUZZ" \
-w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt \
-mc 200,301,302,403 -fc 404 \
-H "Authorization: Bearer $USER_TOKEN" \
-o endpoints.json -of json
ffuf -u "https://target.example.com/api/v1/FUZZ" \
-w /usr/share/seclists/Discovery/Web-Content/api/api-endpoints.txt \
-mc 200,201,204,301,302,401,403,405 -fc 404 \
-H "Authorization: Bearer $USER_TOKEN"
步骤 2 — 配置自动化访问控制测试
设置 Burp Authorize 扩展进行并行的角色测试。
# 安装 Authorize 扩展:
# Burp > Extender > BApp Store > 搜索 "Authorize" > 安装
# 三层测试配置:
# 1. 以管理员身份浏览应用(捕获所有请求)
# 2. 在 Authorize 标签页中:
# a. 在 "Replace cookies/headers" 中添加普通用户的 session token
# b. 可选:添加第二行表示未认证状态(无认证头部)
# 示例头部替换配置:
# 第一行(低权限用户):
# Cookie: session=low_priv_user_session
# Authorization: Bearer low_priv_token
#
# 第二行(未认证):
# [留空 — 移除所有认证头部]
# 在 Authorize 中启用拦截:
# - 勾选 "Intercept requests from Proxy"
# - 勾选 "Intercept requests from Repeater"
# Authorize 结果说明:
# 绿色 = 已正确限制(不同用户响应不同)
# 红色 = 潜在漏洞(无论角色响应相同)
# 橙色 = 不确定(需要手工验证)
步骤 3 — 测试垂直权限提升
使用低权限账户尝试访问高权限功能。
ADMIN_TOKEN="Bearer admin_jwt_here"
MANAGER_TOKEN="Bearer manager_jwt_here"
USER_TOKEN="Bearer user_jwt_here"
ADMIN_ENDPOINTS=(
"GET /admin/dashboard"
"GET /admin/users"
"POST /admin/users/create"
"PUT /admin/settings"
"DELETE /admin/users/5"
"GET /admin/logs"
"GET /admin/reports/export"
"POST /admin/backup"
)
for entry in "${ADMIN_ENDPOINTS[@]}"; do
method=$(echo "$entry" | cut -d' ' -f1)
endpoint=$(echo "$entry" | cut -d' ' -f2)
echo -n "$method $endpoint(以用户身份):"
status=$(curl -s -o /dev/null -w "%{http_code}" \
-X "$method" \
-H "Authorization: $USER_TOKEN" \
-H "Content-Type: application/json" \
"https://target.example.com$endpoint")
if [ "$status" == "200" ] || [ "$status" == "201" ]; then
echo "存在漏洞()"
curl -s -o /dev/null -w \
-X POST \
-H \
-H \
method GET POST PUT PATCH DELETE OPTIONS HEAD;
-n
curl -s -o /dev/null -w \
-X \
-H \
步骤 4 — 测试水平权限提升
验证同一权限级别的用户无法访问其他用户的资源。
USER_A_TOKEN="Bearer user_a_jwt"
RESOURCES=(
"/api/users/102/profile"
"/api/users/102/orders"
"/api/users/102/messages"
"/api/users/102/documents"
"/api/users/102/settings"
"/api/users/102/payment-methods"
)
for resource in "${RESOURCES[@]}"; do
echo -n "GET $resource:"
response=$(curl -s -w "\n%{http_code}" \
-H "Authorization: $USER_A_TOKEN" \
"https://target.example.com$resource")
status=$(echo "$response" | tail -1)
body_len=$(echo "$response" | head -n -1 | wc -c)
if [ "$status" == "200" ] && [ "$body_len" -gt 50 ]; then
echo "存在漏洞($status,$body_len 字节)"
else
echo "正常($status)"
fi
done
curl -s -X PUT \
-H "Authorization: $USER_A_TOKEN" \
-H "Content-Type: application/json" \
-d \
-w
curl -s -X DELETE \
-H \
-w
步骤 5 — 测试功能级访问控制
验证特定功能是否正确执行授权检查。
PROTECTED_ENDPOINTS=(
"/api/user/profile"
"/api/transactions"
"/api/settings"
"/admin/dashboard"
"/api/export/users"
)
for endpoint in "${PROTECTED_ENDPOINTS[@]}"; do
echo -n "无认证:GET $endpoint:"
curl -s -o /dev/null -w "%{http_code}" \
"https://target.example.com$endpoint"
echo
done
curl -s -o /dev/null -w "%{http_code}" \
-H "Authorization: Bearer invalid_token_here" \
"https://target.example.com/api/user/profile"
curl -s -X PUT \
-H "Authorization: $USER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"role":"admin","is_admin":true,"permissions":["admin","superuser"]}' \
"https://target.example.com/api/users/101/profile"
curl -s -X POST \
-H "Content-Type: application/json" \
-d '{"email":"new@test.com","password":"Test123!","role":"admin"}' \
"https://target.example.com/api/auth/register"
步骤 6 — 测试多租户隔离
验证多租户应用中租户边界是否得到强制执行。
TENANT_A_TOKEN="Bearer tenant_a_user_jwt"
curl -s -H "Authorization: $TENANT_A_TOKEN" \
"https://target.example.com/api/organizations/tenant-b-id/users" | jq .
curl -s -H "Authorization: $TENANT_A_TOKEN" \
"https://target.example.com/api/organizations/tenant-b-id/settings" | jq .
curl -s -H "Authorization: $TENANT_A_TOKEN" \
-H "X-Tenant-ID: tenant-b-id" \
"https://target.example.com/api/users" | jq .
curl -s -X POST \
-H "Authorization: $TENANT_A_TOKEN" \
-H "Content-Type: application/json" \
-d '{"tenant_id":"tenant-b-id","query":"SELECT * FROM users"}' \
"https://target.example.com/api/reports/custom"
ffuf -u "https://target.example.com/api/organizations/FUZZ" \
-w <(seq 1 100) \
-H "Authorization: $TENANT_A_TOKEN" \
-mc 200 -t 10 -rate 20
核心概念
| 概念 | 定义 |
|---|
| 垂直权限提升(Vertical Privilege Escalation) | 低权限用户访问高权限功能(用户 -> 管理员) |
| 水平权限提升(Horizontal Privilege Escalation) | 同权限级别的用户访问其他用户的资源 |
| 功能级访问控制(Function-Level Access Control) | 无论 URL 如何,对特定功能/特性的授权检查 |
| RBAC | 基于角色的访问控制 — 权限分配给角色,角色分配给用户 |
| ABAC | 基于属性的访问控制 — 基于用户/资源/环境属性的权限控制 |
| 多租户隔离(Multi-Tenant Isolation) | 确保不同组织/租户之间的数据和功能隔离 |
| 不安全的直接对象引用(Insecure Direct Object Reference) | 通过操控标识符访问对象而无授权检查 |
| 缺失的功能级检查(Missing Function-Level Check) | 端点存在但未验证调用方是否有权限调用 |
工具与系统
| 工具 | 用途 |
|---|
| Burp Suite Professional | 请求拦截和基于角色的测试 |
| Authorize(Burp 扩展) | 跨会话自动化访问控制测试 |
| AutoRepeater(Burp 扩展) | 在不同认证上下文下自动重放请求 |
| Postman | API 测试,在不同角色环境之间切换 |
| ffuf | 发现可能缺少访问控制的隐藏端点 |
| OWASP ZAP | 上下文感知扫描的访问控制测试 |
常见场景
场景 1:管理后台无认证检查
/admin/dashboard 端点在使用普通用户 session token 访问时返回管理后台。前端隐藏了管理菜单,但后端未执行角色检查。
场景 2:API 端点缺少授权
DELETE /api/users/{id} 端点检查了认证(有效 token)但未检查授权(管理员角色)。任何已认证用户都可以删除其他用户的账户。
场景 3:租户数据泄漏
SaaS 应用在 API 请求头部中使用 tenant_id。将 X-Tenant-ID 头部改为另一个租户的 ID 即可返回其数据,绕过租户隔离。
场景 4:批量赋值角色提升
PUT /api/users/{id} 的用户资料更新端点接受 JSON 体中的 role 字段。在资料更新请求中提交 "role":"admin" 即可将用户提权至管理员。
输出格式
## 访问控制缺陷评估报告
**目标**:target.example.com
**评估日期**:2024-01-15
**OWASP 类别**:A01:2021 - 访问控制缺陷
### 访问控制矩阵结果
| 端点 | 管理员 | 经理 | 用户 | 访客 | 预期 | 实际 |
|----------|-------|---------|------|-------|----------|--------|
| GET /admin/dashboard | 200 | 200 | 200 | 302 | 仅管理员 | 失败 |
| DELETE /api/users/{id} | 200 | 200 | 200 | 401 | 仅管理员 | 失败 |
| GET /api/users/other/profile | 200 | 200 | 200 | 401 | 仅本人 | 失败 |
| PUT /api/users/other/settings | 200 | 200 | 200 | 401 | 仅本人 | 失败 |
| GET /api/org/other-tenant | 200 | 200 | 200 | 401 | 同租户 | 失败 |
### 严重发现
1. **垂直提升**:普通用户可访问 /admin/* 端点
2. **水平 IDOR**:用户可读取/修改其他用户的资料
3. **租户隔离**:通过头部操控实现跨租户数据访问
4. **批量赋值**:通过资料更新端点实现角色提升
### 影响
- 任意已认证用户均可获得完整管理员访问权限
- 可访问所有账户的完整用户数据(15,000+ 用户)
- 影响 200+ 组织的跨租户数据泄露
- 通过资料修改实现账户接管
### 建议
1. 在每个端点实施服务端授权检查
2. 使用集中化授权中间件/框架
3. 强制对象级授权(访问前验证所有权)
4. 在服务端验证租户上下文,切勿信任客户端头部
5. 对批量赋值使用白名单(只允许预期字段)
6. 实施对所有访问控制决策的审计日志记录