performing-api-fuzzing-with-restler
使用 Microsoft RESTler 执行有状态 REST API 模糊测试(Fuzzing),通过自动生成并执行测试序列来 覆盖 API 端点,发现请求间的生产者-消费者依赖关系,并找出安全性和可靠性缺陷。 测试人员将 OpenAPI 规范编译为 RESTler 模糊测试语法,配置认证,运行 test/fuzz-lean/fuzz 模式,并分析结果以发现 500 错误、认证绕过、资源泄漏和载荷注入漏洞。 当请求涉及 API 模糊测试、RESTler 测试、有状态 API 测试或自动化 API 安全扫描时触发。
Best use case
performing-api-fuzzing-with-restler is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
使用 Microsoft RESTler 执行有状态 REST API 模糊测试(Fuzzing),通过自动生成并执行测试序列来 覆盖 API 端点,发现请求间的生产者-消费者依赖关系,并找出安全性和可靠性缺陷。 测试人员将 OpenAPI 规范编译为 RESTler 模糊测试语法,配置认证,运行 test/fuzz-lean/fuzz 模式,并分析结果以发现 500 错误、认证绕过、资源泄漏和载荷注入漏洞。 当请求涉及 API 模糊测试、RESTler 测试、有状态 API 测试或自动化 API 安全扫描时触发。
Teams using performing-api-fuzzing-with-restler 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
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/performing-api-fuzzing-with-restler/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How performing-api-fuzzing-with-restler Compares
| Feature / Agent | performing-api-fuzzing-with-restler | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
使用 Microsoft RESTler 执行有状态 REST API 模糊测试(Fuzzing),通过自动生成并执行测试序列来 覆盖 API 端点,发现请求间的生产者-消费者依赖关系,并找出安全性和可靠性缺陷。 测试人员将 OpenAPI 规范编译为 RESTler 模糊测试语法,配置认证,运行 test/fuzz-lean/fuzz 模式,并分析结果以发现 500 错误、认证绕过、资源泄漏和载荷注入漏洞。 当请求涉及 API 模糊测试、RESTler 测试、有状态 API 测试或自动化 API 安全扫描时触发。
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
# 使用 RESTler 执行 API 模糊测试
## 适用场景
- 使用 OpenAPI/Swagger 规范对 REST API 执行自动化安全测试
- 发现只有在特定 API 调用序列下才会出现的缺陷(有状态测试)
- 查找表明存在未处理异常或崩溃条件的 500 内部服务器错误响应
- 通过使用畸形、边界值和注入载荷对参数进行模糊测试来测试 API 输入验证
- 在 CI/CD 流水线中针对 API 变更运行持续的安全回归测试
**不适用于** 在未经明确授权和监控的情况下针对生产环境使用。RESTler 在模糊测试期间会大量创建和删除资源。
## 前置条件
- 明确授权文件,指定目标 API 和可接受的测试范围
- 已安装 Python 3.12+ 和 .NET 8.0 运行时
- 已从 https://github.com/microsoft/restler-fuzzer 下载 RESTler
- 目标 API 的 OpenAPI/Swagger 规范(v2 或 v3)
- API 认证凭据(令牌、API 密钥或 OAuth 凭据)
- 隔离的测试/预发布环境(RESTler 每小时可创建数千个资源)
## 工作流程
### 步骤 1:RESTler 安装与配置
```bash
# 克隆并构建 RESTler
git clone https://github.com/microsoft/restler-fuzzer.git
cd restler-fuzzer
# 构建 RESTler
python3 ./build-restler.py --dest_dir /opt/restler
# 验证安装
/opt/restler/restler/Restler --help
# 替代方案:使用预构建的发布版本
# 从 https://github.com/microsoft/restler-fuzzer/releases 下载
```
### 步骤 2:编译 API 规范
```bash
# 将 OpenAPI 规范编译为 RESTler 模糊测试语法
/opt/restler/restler/Restler compile \
--api_spec /path/to/openapi.yaml
# 输出目录结构:
# Compile/
# grammar.py - 生成的模糊测试语法
# grammar.json - JSON 格式的语法
# dict.json - 用于模糊测试值的自定义字典
# engine_settings.json - 引擎配置
# config.json - 编译配置
```
**用于定向模糊测试的自定义字典(dict.json):**
```json
{
"restler_fuzzable_string": [
"fuzzstring",
"' OR '1'='1",
"\" OR \"1\"=\"1",
"<script>alert(1)</script>",
"../../../etc/passwd",
"${7*7}",
"{{7*7}}",
"a]UNION SELECT 1,2,3--",
"\"; cat /etc/passwd; echo \"",
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
],
"restler_fuzzable_int": [
"0",
"-1",
"999999999",
"2147483647",
"-2147483648"
],
"restler_fuzzable_bool": ["true", "false", "null", "1", "0"],
"restler_fuzzable_datetime": [
"2024-01-01T00:00:00Z",
"0000-00-00T00:00:00Z",
"9999-12-31T23:59:59Z",
"invalid-date"
],
"restler_fuzzable_uuid4": [
"00000000-0000-0000-0000-000000000000",
"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
],
"restler_custom_payload": {
"/users/{userId}": ["1", "0", "-1", "admin", "' OR 1=1--"],
"/orders/{orderId}": ["1", "0", "999999999"]
}
}
```
### 步骤 3:配置认证
```python
# authentication_token.py - RESTler 认证模块
import requests
import json
import time
class AuthenticationProvider:
def __init__(self):
self.token = None
self.token_expiry = 0
self.auth_url = "https://target-api.example.com/api/v1/auth/login"
self.credentials = {
"email": "fuzzer@test.com",
"password": "FuzzerPass123!"
}
def get_token(self):
"""获取或刷新认证令牌。"""
current_time = time.time()
if self.token and current_time < self.token_expiry - 60:
return self.token
resp = requests.post(self.auth_url, json=self.credentials)
if resp.status_code == 200:
data = resp.json()
self.token = data["access_token"]
self.token_expiry = current_time + 3600 # 假设 1 小时有效期
return self.token
else:
raise Exception(f"认证失败:{resp.status_code}")
def get_auth_header(self):
"""返回 RESTler 使用的认证请求头。"""
token = self.get_token()
return f"Authorization: Bearer {token}"
# 导出 RESTler 使用的令牌刷新命令
auth = AuthenticationProvider()
print(auth.get_auth_header())
```
**用于认证的引擎设置(engine_settings.json):**
```json
{
"authentication": {
"token": {
"token_refresh_interval": 300,
"token_refresh_cmd": "python3 /path/to/authentication_token.py"
}
},
"max_combinations": 20,
"max_request_execution_time": 30,
"global_producer_timing_delay": 2,
"no_ssl": false,
"host": "target-api.example.com",
"target_port": 443,
"garbage_collection_interval": 300,
"max_sequence_length": 10
}
```
### 步骤 4:以测试模式运行 RESTler(冒烟测试)
```bash
# 测试模式:快速验证所有端点是否可达
/opt/restler/restler/Restler test \
--grammar_file Compile/grammar.py \
--dictionary_file Compile/dict.json \
--settings Compile/engine_settings.json \
--no_ssl \
--target_ip target-api.example.com \
--target_port 443
# 查看测试结果
cat Test/ResponseBuckets/runSummary.json
```
```python
# 解析测试结果
import json
with open("Test/ResponseBuckets/runSummary.json") as f:
summary = json.load(f)
print("测试模式摘要:")
print(f" 总请求数:{summary.get('total_requests_sent', {}).get('num_requests', 0)}")
print(f" 成功(2xx):{summary.get('num_fully_valid', 0)}")
print(f" 客户端错误(4xx):{summary.get('num_invalid', 0)}")
print(f" 服务器错误(5xx):{summary.get('num_server_error', 0)}")
# 识别未覆盖的端点
covered = summary.get('covered_endpoints', [])
total = summary.get('total_endpoints', [])
uncovered = set(total) - set(covered)
if uncovered:
print(f"\n未覆盖的端点({len(uncovered)} 个):")
for ep in uncovered:
print(f" - {ep}")
```
### 步骤 5:运行 Fuzz-Lean 模式
```bash
# fuzz-lean:启用安全检查器对所有端点进行一轮遍历
/opt/restler/restler/Restler fuzz-lean \
--grammar_file Compile/grammar.py \
--dictionary_file Compile/dict.json \
--settings Compile/engine_settings.json \
--target_ip target-api.example.com \
--target_port 443 \
--time_budget 1 # 最长 1 小时
# fuzz-lean 中自动启用的检查器:
# - UseAfterFree:测试删除后访问资源
# - NamespaceRule:测试跨命名空间/租户访问资源
# - ResourceHierarchy:使用错误父资源 ID 测试子资源
# - LeakageRule:测试错误响应中的信息泄露
# - InvalidDynamicObject:使用畸形动态对象 ID 进行测试
```
### 步骤 6:运行完整模糊测试模式
```bash
# 完整模糊测试模式:扩展模糊测试以获得全面覆盖
/opt/restler/restler/Restler fuzz \
--grammar_file Compile/grammar.py \
--dictionary_file Compile/dict.json \
--settings Compile/engine_settings.json \
--target_ip target-api.example.com \
--target_port 443 \
--time_budget 4 \
--enable_checkers UseAfterFree NamespaceRule ResourceHierarchy LeakageRule InvalidDynamicObject PayloadBody
# 分析模糊测试结果
python3 <<'EOF'
import json
import os
results_dir = "Fuzz/ResponseBuckets"
bugs_dir = "Fuzz/bug_buckets"
# 解析缺陷桶
if os.path.exists(bugs_dir):
for bug_file in os.listdir(bugs_dir):
if bug_file.endswith(".txt"):
with open(os.path.join(bugs_dir, bug_file)) as f:
content = f.read()
print(f"\n=== 缺陷:{bug_file} ===")
print(content[:500])
# 解析响应摘要
summary_file = os.path.join(results_dir, "runSummary.json")
if os.path.exists(summary_file):
with open(summary_file) as f:
summary = json.load(f)
print(f"\n模糊测试摘要:")
print(f" 持续时间:{summary.get('time_budget_hours', 0)} 小时")
print(f" 总请求数:{summary.get('total_requests_sent', {}).get('num_requests', 0)}")
print(f" 发现缺陷数:{summary.get('num_bugs', 0)}")
print(f" 500 错误数:{summary.get('num_server_error', 0)}")
EOF
```
## 核心概念
| 术语 | 定义 |
|------|------|
| **有状态模糊测试(Stateful Fuzzing)** | 通过使用早期请求的响应作为后续请求的输入来维持跨请求状态的 API 模糊测试,可测试多步骤工作流 |
| **生产者-消费者依赖(Producer-Consumer Dependencies)** | RESTler 的推断机制:一个 API 调用产生的值(如创建的资源 ID)应被后续调用所消费 |
| **模糊测试语法(Fuzzing Grammar)** | API 规范的编译表示,定义如何为每个端点生成有效和无效的请求 |
| **检查器(Checker)** | 测试特定漏洞模式(如释放后使用、命名空间隔离或信息泄露)的 RESTler 安全规则 |
| **缺陷桶(Bug Bucket)** | RESTler 按类型和端点对发现的缺陷进行分类,将类似故障分组以便高效分诊 |
| **垃圾回收(Garbage Collection)** | RESTler 定期清理在模糊测试期间创建的资源,防止目标系统资源耗尽 |
## 工具与系统
- **RESTler**:Microsoft Research 的有状态 REST API 模糊测试工具,将 OpenAPI 规范编译为模糊测试语法
- **Schemathesis**:基于属性的 API 测试工具,从 OpenAPI/GraphQL 模式生成测试用例
- **Dredd**:根据 OpenAPI/API Blueprint 文档验证 API 实现的测试工具
- **Fuzz-lightyear**:Yelp 的无状态 API 模糊器,专注于发现认证和授权漏洞
- **API Fuzzer**:OWASP 的 API 端点模糊测试工具,支持自定义载荷字典
## 常见场景
### 场景:微服务 API 模糊测试活动
**场景背景**:一家金融科技公司拥有 12 个配有 OpenAPI 规范的微服务 API。在重大发布前,安全团队在预发布环境中对每个服务运行 RESTler 模糊测试以发现缺陷。
**方法**:
1. 收集所有 12 个服务的 OpenAPI 规范,将每个规范编译为 RESTler 语法
2. 使用服务专属凭据为每个服务配置认证
3. 对每个服务运行测试模式,验证端点可达性并修复语法问题
4. 对每个服务运行 fuzz-lean 模式(每服务 1 小时)以快速发现问题
5. 在 fuzz-lean 模式中发现 23 个缺陷:8 个未处理的 500 错误、5 个释放后使用模式、4 个命名空间隔离失败、6 个错误响应中的信息泄露
6. 对缺陷最多的 5 个服务运行完整模糊测试模式(每服务 4 小时)
7. 发现 47 个额外缺陷,包括一个严重的认证绕过:删除用户后重用其令牌仍可访问
8. 生成缺陷报告并通过 JIRA 集成跟踪修复进度
**常见陷阱**:
- 未了解 RESTler 会创建和删除数千个资源,就对生产环境运行
- 未正确配置认证,导致 RESTler 只测试未认证访问
- 使用默认字典,未添加应用特定的注入载荷
- 未设置时间预算,导致 RESTler 无限运行
- 忽略编译警告,这些警告指示 RESTler 因依赖问题无法到达的端点
## 输出格式
```
## RESTler API 模糊测试报告
**目标**:用户服务 API(staging.example.com)
**规范**:OpenAPI 3.0(42 个端点)
**持续时间**:4 小时(完整模糊测试模式)
**总请求数**:145,832
### 缺陷摘要
| 类别 | 数量 | 严重性 |
|----------|-------|----------|
| 500 内部服务器错误 | 12 | 高 |
| 释放后使用 | 3 | 严重 |
| 命名空间规则违规 | 5 | 严重 |
| 信息泄露 | 8 | 中 |
| 资源泄漏 | 4 | 低 |
### 关键发现
**1. 释放后使用:已删除用户的令牌仍然有效**
- 序列:POST /users -> DELETE /users/{id} -> GET /users/{id}
- 删除用户后,使用已删除用户的令牌发送 GET 请求返回 200
- 影响:已删除账户仍可访问 API
**2. 命名空间违规:跨租户数据访问**
- 序列:POST /users(租户 A)-> GET /users/{id}(租户 B 令牌)
- 租户 A 创建的用户可通过租户 B 的凭据访问
- 影响:多租户隔离被突破
**3. 500 错误:未处理的整数溢出**
- 请求:POST /orders {"quantity": 2147483648}
- 响应:500 内部服务器错误,包含堆栈跟踪
- 影响:DoS 潜力,通过堆栈跟踪造成信息泄露
### 覆盖率
- 端点覆盖:38/42(90.5%)
- 未覆盖:POST /admin/migrate、DELETE /admin/cache、
PUT /config/advanced、POST /webhooks/test
```Related Skills
performing-yara-rule-development-for-detection
通过识别可执行文件中的唯一字节模式、字符串和行为指标,开发精准的 YARA 恶意软件检测规则,同时将误报率降至最低。
performing-wireless-security-assessment-with-kismet
使用 Kismet 通过被动射频监控进行无线网络安全评估,检测流氓接入点(Rogue AP)、隐藏 SSID、弱加密和未授权客户端。
performing-wireless-network-penetration-test
执行无线网络渗透测试,通过捕获握手包、破解 WPA2/WPA3 密钥、检测流氓接入点以及使用 Aircrack-ng 和相关工具测试无线网络分段,评估 WiFi 安全性。
performing-windows-artifact-analysis-with-eric-zimmerman-tools
使用 Eric Zimmerman 的开源 EZ Tools 套件(包括 KAPE、MFTECmd、PECmd、LECmd、JLECmd 和 Timeline Explorer)执行全面的 Windows 取证制品分析,解析注册表 hive、预取文件、事件日志和文件系统元数据。
performing-wifi-password-cracking-with-aircrack
在授权无线安全评估中捕获 WPA/WPA2 握手包,并使用 aircrack-ng、hashcat 和字典攻击进行离线密码破解, 以评估密码短语强度和无线网络安全状况。
performing-web-cache-poisoning-attack
在授权安全测试期间,通过未纳入缓存键的头部和参数毒化缓存响应,利用 Web 缓存机制向其他用户投递恶意内容。
performing-web-cache-deception-attack
通过利用 CDN 缓存层与源服务器之间的路径规范化差异,执行 Web 缓存欺骗攻击,从而缓存并获取敏感的已认证内容。
performing-web-application-vulnerability-triage
使用 OWASP 风险评级方法论对 DAST/SAST 扫描器的 Web 应用程序漏洞发现进行分类,区分真阳性和假阳性,并确定修复优先级。
performing-web-application-scanning-with-nikto
Nikto 是一款开源 Web 服务器和 Web 应用程序扫描器,可针对超过 7,000 个潜在危险文件/程序进行测试,检查超过 1,250 个服务器的过期版本,并识别超过 270 个服务器的版本特定问题。
performing-web-application-penetration-test
遵循 OWASP Web 安全测试指南(WSTG)方法论,对 Web 应用程序执行系统化安全测试,识别认证、授权、 输入验证、会话管理和业务逻辑中的漏洞。测试人员以 Burp Suite 作为主要拦截代理,结合手动测试技术 发现自动化扫描器遗漏的缺陷。适用于 Web 应用渗透测试、OWASP 测试、应用安全评估或 Web 漏洞测试等请求场景。
performing-web-application-firewall-bypass
使用编码技术、HTTP 方法操控、参数污染和载荷混淆绕过 Web 应用防火墙保护,将 SQL 注入、XSS 及其他攻击载荷穿透 WAF 检测规则。
performing-vulnerability-scanning-with-nessus
使用 Tenable Nessus 执行认证和未认证漏洞扫描,识别网络基础设施、服务器和应用程序中的已知漏洞、 错误配置、默认凭据和缺失补丁。扫描器将发现与 CVE 数据库和 CVSS 评分关联,生成优先级修复指导。 适用于漏洞扫描、Nessus 评估、补丁合规检查或自动化漏洞检测等请求场景。