Autore: Matteo Brandi (Team Hackerhood)
Il più delle volte sentiamo parlare delle SQL injection.
Ma per i database NoSQL non c’è niente?
No perchè se non ci fosse niente allora sarebbero ultra sicuri… e invece, le injection ci sono
anche per loro!
Seguimi in questo viaggio del terrore per la sicurezza dei database NoSQL.
INTRODUZIONE
Ripasso veloce sui database NoSQL in forma di tabella:

Ma se vuoi sapere perché e come…devi leggere fino in fondo.
Ancora un pò di noia con la classificazione dei NoSQL injection, poi vedrai che arriva la
parte succulenta:
In-Band: quando l’aggressore può utilizzare lo stesso canale di comunicazione per sfruttare
una NoSQL injection e ricevere i risultati.
Blind:quando l’aggressore non riceve alcun risultato diretto dall’iniezione NoSQL ma può
dedurli in base alla risposta del server.
Boolean:una tecnica in cui gli aggressori possono forzare il server a valutare una query e
restituire un risultato di vero o falso.
Time-Based: quando gli aggressori fanno attendere il server per un determinato periodo di
tempo prima di rispondere, solitamente per indicare se la query viene valutata come vera o
falsa.
Premessa: ci occuperemo solamente delle chiamate http POST perchè le GET hanno delle
particolarità che qualche volta le rendono immuni a questo attacco.
Costruiamo il nostro scenario (chiudi gli occhi e immagina…): un servizio API che consenta
di avere informazioni sugli utenti a partire dal nome utente scritto in NodeJS e come database
MongoDB.
Ecco il codice della nostra semplicissima API:

Quando effettui una chiamata al servizio, devi passare un nome utente a noto per avere i
dati

L’ATTACCO
Se tu volessi i dati di tutto il reame?
Qui entra in gioco la injection: basta usare le espressioni tipiche del linguaggio del database
NoSQL ed il gioco è fatto :
Al posto di “utente2” nella richiesta basta scrivere
{“$regex”:”.*”}
ed il gioco è fatto come puoi vedere nella figura sotto.

Tradotta: dammi i dati dove il nome utente corrisponda a qualsiasi carattere.
Se ti stai chiedendo perchè restituisce solo 2 utenti…è perchè due ne ho inseriti.
Come avrai notato, rispetto alle SQL injection, qui non c’è necessità di interrompere con gli
apici per uscire dalla variabile e continuare la query, basta riuscire ad inserire una specifica
espressione tra quelle codificate nel linguaggio.
Un altro esempio possibile è usare l’espressione
{“$ne”:””}
dove ne sta per not equal , quindi restituiscimi tutti i dati dove il nome utente non è vuoto.

Si può usare l’espressione:
{“$gt”:””}
che sta per greater than : restituiscimi tutti i dati dove il nome utente non è maggiore di
niente.

Le possibili condizioni da inserire non finiscono qui.
Esistono anche i seguenti operatori:
$eq equal to
$gte greater than or equal to
$in in the specifies array
$lt less than
$and operatore and
$not operatore not
$where operatore where
L’attacco qui è stato portato per esfiltrare dati, ma può essere portato anche per bypassare
una autenticazione.
Immagina un acco ad un portale web : inserendo la condizione:
{“$ne”:””}
Sia nello user name che nella password, si può ottenere l’accesso.
Un’altra possibilità di attacco sta nella capacità di inserire codice javascript arbitrario nel
contesto del database.

utilizzando l’operatore $where.
Un attaccante potrebbe passare questa stringa siano come username che come password:
” || “”==”
facendo si che il server esegua la seguente query:
db.users.find({$where: ‘this.username == “” || “”==”” && this.password == “” || “”==””‘})
consentendo l’accesso in quanto sempre vera.
L’operatore || è un operatore OR in javascript.
Dove sta il problema?
PREVENIRE LA NoSQL INJECTION
Come avrai già letto prima, è un problema di igiene degli input.
Questo è il pezzo di codice che crea il disastro:

Non essendoci nessuna validazione né sanitizzazione dell’input, un attaccante riuscirebbe a
inserire l’injection molto facilmente.
Le principali soluzioni non sono diverse da quelle per le SQL injection:
- Mai usare i dati degli input “as is” , validarli e sanitizzarli attraverso espressioni
regolari e white list di dati accettabili - Usare solo query parametrizzate
- Trasformare gli input in stringhe
Per il momento è tutto…restate sintonizzati che i problemi non finiscono certamente qui.
Comments are closed