Race conditions
Una vulnerabilità di tipo race condition è una vulnerabilità logica che può sorgere durante la gestione di richieste concorrenti che utilizzano una risorsa condivisa, ma non implementano meccanismi di sincronizzazione.
Supponiamo di avere una applicazione web che nel piano semplice ci permetta di gestire fino a 3 progetti, e che per gestirne di più ci faccia pagare. Supponiamo che il codice sia scritto in questa maniera:
$result = $db->exec("SELECT COUNT(*) as how_many_projects FROM projects WHERE user_id = ?", [$_SESSION["user_id"]]);
if($result['how_many_projects'] < 3){
$db->exec("INSERT INTO projects (name, user_id) VALUES(?, ?)", [$_POST["project_name"], $_SESSION["user_id"]]);
echo "Progetto creato correttamente";
}
else{
echo "Hai superato il numero di progetti per il tuo piano";
}
Il flusso di esecuzione di una singola richiesta è schematizzabile come:

quindi la logica funziona e non possiamo creare più di 3 progetti.
Ora lanciamo le richieste in parallelo e proviamo a supporre cosa possa succedere:

nel caso di due richieste concorrenti può succedere (e all'aumentare del numero di richieste concorrenti, la probabilità diventa certezza) che le query che calcolano il numero di progetti ora presenti siano entrambe eseguite prima delle query che aggiungono progetti.
Dato che non ci sono meccanismi per garantire la sincronizzazione di queste richieste, lanciano più richieste in parallelo si può oltrepassare questo limite.
TOCTOU
La vulnerabilità presentata sopra prende il nome di Time-of-check time-of-use (TOCTOU) in quanto nella finestra tra il controllo di una proprietà e la sua modifica, essa viene modificata. Le TOCTOU non esistono solo in ambito web, anzi, ci sono esempi famosi di TOCTOU all'interno di server mail ed SSH che hanno compromesso la sicurezza di alcune versioni di questi servizi.
Mitigazioni
Per mitigare una vulnerabilità di tipo TOCTOU bisogna prima di tutto capire quale è la causa di questa mancanza di sincronizzazione, dopo di che bisogna capire dove è più opportuno implementare dei lock sulle risorse. Vediamo alcuni esempi:
- TOCTOU nei database: l'esempio precedente può essere mitigato usando le transazioni e prendendo i lock sulle tabelle che si vogliono andare a modificare.
- TOCTOU nel file system: tra il controllo che un file non esista e la sua apertura potremmo creare un symbolic link, in questo modo l'applicazione andrà ad aprire un file scelto da noi.
Per mitigare questo scenario possiamo chiedere al sistema operativo di aprire il file se e solo se non esiste già passando i flag
O_EXCL | O_CREATalla funzioneopen.