BOLA (Broken Object Level Authorization), nota anche come IDOR (Insecure Direct Object Reference) in contesto web generico, è la vulnerabilità più frequente nelle API REST secondo l’OWASP API Security Top 10. Si manifesta quando un endpoint accetta un identificatore di risorsa (ID, UUID, slug) dall’utente e vi accede senza verificare che l’utente corrente sia autorizzato a operare su quella specifica risorsa.
La distinzione tra BOLA e IDOR è principalmente di contesto: IDOR è il termine storico usato nell’OWASP Top 10 per le applicazioni web tradizionali; BOLA è la denominazione introdotta dall’OWASP API Security Top 10 (2019, 2023) per enfatizzare il problema nelle API REST e GraphQL.
Meccanismo
Un’API espone gli ordini di un utente:
GET /api/v1/ordini/1842
Authorization: Bearer <token_utente_A>
Il server verifica che il token sia valido (autenticazione), ma non verifica che l’ordine 1842 appartenga all’utente A (autorizzazione a livello di oggetto). Un attaccante autenticato come utente B invia:
GET /api/v1/ordini/1841
Authorization: Bearer <token_utente_B>
Riceve i dati dell’ordine di utente A. Iterando sugli ID (1840, 1841, 1842, …) ottiene tutti gli ordini del sistema — un attacco di enumerazione.
Perché è così diffusa
Le API REST espongono identificatori di risorse per design — è la convenzione stessa di REST (/utenti/{id}, /documenti/{id}). Il rischio è strutturale: ogni endpoint che accetta un ID è potenzialmente vulnerabile se il controllo di autorizzazione è assente o incompleto.
La vulnerabilità è difficile da rilevare con scanner automatici: il server risponde 200 OK sia per richieste legittime che per accessi non autorizzati — non c’è un pattern di errore da rilevare.
Varianti
BOLA verticale (privilege escalation): l’accesso non autorizzato è verso risorse di un ruolo superiore (es. utente normale accede a risorse admin), non solo di un altro utente dello stesso livello.
BOLA su operazioni di scrittura: non solo lettura ma modifica o cancellazione di risorse altrui:
DELETE /api/v1/documenti/9901
Authorization: Bearer <token_utente_diverso>
BOLA su oggetti annidati: l’autorizzazione è verificata sull’oggetto padre ma non sugli oggetti figli:
GET /api/v1/progetti/5/commenti/3392
# Il server verifica l'accesso al progetto 5 ma non se il commento 3392 appartiene davvero a quel progetto
BOLA su ID non sequenziali: usare UUID v4 invece di interi sequenziali riduce la discoverability (non si può enumerare facilmente) ma non elimina la vulnerabilità — se l’UUID è ottenibile tramite altre API o leak, l’accesso non autorizzato è ancora possibile.
BOLA in GraphQL: le query GraphQL permettono di richiedere risorse con ID arbitrari attraverso campi annidati — ogni campo che espone un ID è un potenziale punto di BOLA.
Contromisure
Autorizzazione a livello di oggetto per ogni richiesta: il principio fondamentale è che l’autenticazione (chi sei) e l’autorizzazione sull’oggetto (puoi accedere a questo specifico oggetto?) sono controlli separati e indipendenti:
# Codice sicuro
def get_ordine(ordine_id, utente_corrente):
ordine = db.query("SELECT * FROM ordini WHERE id = ?", ordine_id)
if ordine is None:
raise NotFoundError()
# Controllo autorizzazione a livello di oggetto
if ordine.utente_id != utente_corrente.id:
raise ForbiddenError() # 403, non 404
return ordine
Query con ownership implicita: costruire le query in modo che l’ownership sia parte della condizione SQL, non un controllo separato successivo:
-- Sicuro: l'utente_id è parte del WHERE, non può ottenere ordini di altri
SELECT * FROM ordini WHERE id = ? AND utente_id = ?
Policy di autorizzazione centralizzata: usare librerie di autorizzazione (es. Casbin, OPA, Pundit per Rails) che centralizzano le regole e le applicano uniformemente, riducendo il rischio di dimenticanze.
Test sistematici di autorizzazione orizzontale: creare almeno due utenti test e verificare che le risorse dell’uno non siano accessibili all’altro — per ogni endpoint dell’API.
Risposta uniforme: restituire 403 Forbidden (o 404 Not Found se si vuole nascondere l’esistenza della risorsa) sia quando la risorsa non esiste sia quando l’utente non è autorizzato — evitare di distinguere i due casi con codici diversi che fornirebbero informazioni all’attaccante.
Relazione con altri argomenti
- IDOR — termine equivalente in contesto web tradizionale.
- OWASP Top 10 — A01 Broken Access Control comprende BOLA/IDOR.
- Mass Assignment — vulnerabilità correlata: BOLA riguarda quale oggetto accedere, mass assignment riguarda quali campi modificare.
- Controllo degli Accessi — il modello generale di autorizzazione di cui BOLA è una violazione.
- Penetration Testing — BOLA è sistematicamente testata nelle valutazioni di API security.