it-swarm.com.de

MongoDB Nosql-Injektion in python Code

Hier ist das Code-Snippet für den Zugriff auf 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 = ""

Mir wurde gesagt, dass dieser Code für die NoSQL-Injektion anfällig ist, da die Bedingungsvariable nicht ordnungsgemäß bereinigt wird. Aber ich konnte nicht herausfinden, wie die Injektion mit Python funktioniert. Kann mir jemand ein Beispiel geben, wie die Eingabe die Probleme verursachen kann, oder einige Hinweise auf verwandte Injektionsangriffe? Übrigens habe ich auch selbst recherchiert, aber nur die Injektion basierend auf Javascript gefunden und versucht, in diesem Fall nicht zu funktionieren. Vielen Dank.

11
Yang Yu

Der Operator $where In MongoDB ist eine Funktion, die am besten vermieden wird. Die Leistung ist miserabel und nicht nur, weil es nicht von Indizes profitiert. Fast jeder gängige Anwendungsfall kann mit einer gemeinsamen Suchabfrage oder Aggregation viel effizienter gelöst werden, insbesondere mit einer so trivialen. Dies ist jedoch ein Sicherheitsstapelaustausch, kein Stapelüberlauf. Konzentrieren wir uns also auf die Auswirkungen auf die Sicherheit.

Die Anweisung $where Übergibt ein Javascript-Code-Snippet an die Datenbank, das die Datenbank dann für jedes Dokument in der Sammlung einmal ausführt. Zum Glück hat dieses Skript keinen Zugriff auf das db -Objekt und andere gefährliche Shell-Funktionen und funktioniert mit Kopien der Dokumente, sodass der Angreifer den Datenbankinhalt zumindest nicht wie bei vielen SQL-Injektionen ändern kann. Es ist jedoch beispielsweise anfällig für Angriffe, bei denen der Angreifer andere als die beabsichtigten Ergebnisse zurückgeben möchte.

Lassen Sie uns ein Beispiel machen. Nehmen wir an, wir haben einen Blog. Unser Blog enthält viele Artikel, die öffentlich gelesen werden können, aber wir haben auch einige private Artikel, die für unseren internen Gebrauch bestimmt sind und nicht veröffentlicht werden sollen. Wir haben also ein Feld hidden in unseren Dokumenten, das true oder false sein kann, je nachdem, ob unsere Besucher den Artikel sehen sollen oder nicht. Unsere MongoDB-Abfrage, um eine Liste aller Artikel in einer bestimmten Kategorie zu erhalten, um sie dem Website-Besucher anzuzeigen, sieht folgendermaßen aus:

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

Das sollte sicherstellen, dass niemand unsere versteckten Artikel ansieht. Oder doch? Wenn der Benutzer die Variable category- steuert, kann er diese Zeichenfolge festlegen:

'; return '' == '

Das resultierende Javascript-Snippet, das an die Datenbank gesendet wird, lautet wie folgt:

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

Wenn Sie ein Javascript-Snippet mit mehreren durch ; Getrennten Befehlen haben, werden diese als Funktion ausgeführt und eine return - Anweisung wird benötigt, um zu bestimmen, welcher Wert an den Aufrufer zurückgegeben wird. Diese Funktion gibt immer true zurück. Das bedeutet, dass der Benutzer auch alle Artikel in unserer Sammlung sieht, einschließlich derjenigen, die versteckt sein sollen.

15
Philipp

Kann mir jemand ein Beispiel geben, wie die Eingabe die Probleme verursachen kann

Für Ihren konkreten Code sollte dies funktionieren:

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

'; Wird verwendet, um den String und die Anweisung zu maskieren, folgt dann dem tatsächlichen Angriff while(1); (DOS-Angriff), und dann wird das noch stehende ' Über in eine gültige Syntax umgewandelt var foo='bar.

Bis zur Version 2.4 von MongoDB war das Objekt db tatsächlich global, sodass Sie die Daten in der Datenbank ändern und sogar Daten mit Blindinjektion abrufen .

Da dies nicht mehr möglich ist, kann ein Angreifer höchstens DOS und die von Philipp beschriebene Filterhinterziehung tun (was für Ihr Beispiel kein Problem wäre, aber im Allgemeinen ein Problem sein kann).

Das ist immer noch ziemlich schlecht, also sollten Sie sich dagegen verteidigen, indem Sie ', " Und $ Entkommen.

8
tim