MongoDB Iniezione di Nosql in codice Python

10

Ecco lo snippet di codice per accedere a MongoDB.

client = MongoClient()
db = client.test_database
collection = db.test

# Get data from fields
condition = form.getvalue('name')
if condition:
    where = {"$where": "this.name == '"+condition+"'" }
else:
    where = ""

Mi è stato detto che questo codice è vulnerabile all'iniezione NoSQL poiché la variabile di condizione non è correttamente disinfettata. Ma non riuscivo a capire come funziona l'iniezione con Python. Qualcuno può darmi un esempio come l'input può causare i problemi o alcuni riferimenti al relativo attacco di iniezione? A proposito, ho anche fatto delle ricerche da solo, ma ho trovato l'iniezione basata su Javascript e ho cercato di non funzionare in questo caso. Grazie.

    
posta Yang Yu 07.03.2015 - 00:35
fonte

2 risposte

12

L'operatore $where in MongoDB è una funzione che è meglio evitare. Le sue prestazioni sono abissali e non solo perché non beneficiano degli indici. Quasi tutti i casi d'uso comuni possono essere risolti in modo molto più efficiente con una query di ricerca o aggregazione comune, in particolare una banale come questa. Ma questo è security stackexchange, non stackoverflow, quindi concentriamoci sulle implicazioni per la sicurezza.

L'istruzione $where passa uno snippet di codice javascript al database che il database eseguirà una volta per ciascun documento nella raccolta. Fortunatamente questo script non ha accesso all'oggetto db e ad altre pericolose funzioni della shell e funziona su copie dei documenti, quindi l'autore dell'attacco può almeno non modificare il contenuto del database come con molte iniezioni SQL. Ad esempio, è vulnerabile agli attacchi in cui l'autore dell'attacco desidera restituire altri risultati rispetto a quanto previsto.

Facciamo un esempio. Diciamo che abbiamo un blog. Il nostro blog ha molti articoli che possono essere letti in pubblico, ma abbiamo anche alcuni articoli privati che sono per uso interno e che non dovrebbero essere pubblicati. Quindi abbiamo un campo hidden nei nostri documenti che può essere true o false a seconda che i nostri visitatori debbano o meno vedere l'articolo. La nostra query MongoDB per ottenere un elenco di tutti gli articoli in una determinata categoria per visualizzarla al visitatore del sito Web è simile alla seguente:

db.articles.find({"$where": "this.hidden == false && this.category == '"+category+"'" });

Questo dovrebbe fare in modo che nessuno guardi i nostri articoli nascosti. O lo fa? Quando l'utente controlla la variabile category , può impostarla su questa stringa:

'; return '' == '

Lo snippet di Javascript risultante che viene inviato al database è questo:

this.hidden == false && this.category == ''; return '' == ''

Quando hai uno snippet di javascript con più comandi separati da ; , saranno eseguiti come una funzione e un'istruzione return è necessaria per determinare quale valore verrà passato al chiamante. Questa funzione restituirà sempre true. Ciò significa che l'utente vedrà anche tutti gli articoli della nostra collezione, inclusi quelli che dovrebbero essere nascosti.

    
risposta data 07.03.2015 - 01:02
fonte
7

Can anyone give me an example like what input may cause the issues

Per la tua parte concreta di codice dovrebbe funzionare:

'; while(1);var foo='bar

'; viene usato per sfuggire alla stringa e all'istruzione, quindi segue l'attacco effettivo while(1); (attacco DOS), quindi il ' ancora in piedi viene trasformato in sintassi valida tramite var foo='bar .

Fino alla versione 2.4 di MongoDB, l'oggetto db era effettivamente globale, quindi è possibile modificare i dati nel database e anche recupera i dati utilizzando l'iniezione cieca .

Poiché ciò non è più possibile, il massimo che un attacker può fare è DOS e l'evasione del filtro descritta da Philipp (che non sarebbe un problema per il tuo esempio, ma può essere un problema in generale).

È ancora piuttosto brutto, quindi dovresti difenderti sfidando ' , " e $ .

    
risposta data 07.03.2015 - 10:54
fonte

Leggi altre domande sui tag