MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

MongoDB vor externen Injection-Angriffen schützen

MongoDB-Sicherheit wird nicht vollständig garantiert, indem einfach Authentifizierungszertifikate konfiguriert oder die Daten verschlüsselt werden. Einige Angreifer gehen noch einen Schritt weiter, indem sie mit den empfangenen Parametern in HTTP-Anforderungen spielen, die als Teil des Abfrageprozesses der Datenbank verwendet werden.

SQL-Datenbanken sind am anfälligsten für diese Art von Angriffen, aber externe Injektion ist auch in NoSQL-DBMs wie MongoDB möglich. In den meisten Fällen treten externe Injektionen als Ergebnis einer unsicheren Verkettung von Zeichenfolgen beim Erstellen von Abfragen auf.

Was ist ein externer Injection-Angriff?

Code-Injektion ist im Grunde das Integrieren nicht validierter Daten (ungemilderter Vektor) in ein verwundbares Programm, das, wenn es ausgeführt wird, zu einem katastrophalen Zugriff auf Ihre Datenbank führt; seine Sicherheit bedrohen.

Wenn unsaubere Variablen an eine MongoDB-Abfrage übergeben werden, unterbrechen sie die Orientierungsstruktur der Dokumentabfrage und werden manchmal als Javascript-Code selbst ausgeführt. Dies ist häufig der Fall, wenn Requisiten direkt vom Body-Parser-Modul für den Nodejs-Server übergeben werden. Daher kann ein Angreifer leicht ein Js-Objekt einfügen, wo Sie eine Zeichenfolge oder Zahl erwarten würden, wodurch unerwünschte Ergebnisse erzielt oder Ihre Daten manipuliert werden.

Betrachten Sie die folgenden Daten in der Sammlung eines Schülers.

{username:'John Doc', email:'[email protected]', age:20},

{username:'Rafael Silver', email:'[email protected]', age:30},

{username:'Kevin Smith', email:'[email protected]', age:22},

{username:'Pauline Wagu', email:'[email protected]', age:23}

Nehmen wir an, Ihr Programm muss alle Schüler abholen, deren Alter gleich 20 ist. Sie würden einen Code wie diesen schreiben...

app.get(‘/:age’, function(req, res){

  db.collections(“students”).find({age: req.params.age});

})

Sie haben in Ihrer http-Anfrage ein JSON-Objekt als 

gesendet
{age: 20}

Dies gibt alle Schüler zurück, deren Alter gleich 20 ist, als erwartetes Ergebnis und in diesem Fall nur {username:'John Doc', email:'[email protected]', age:20} .

Nehmen wir nun an, ein Angreifer übermittelt ein Objekt anstelle einer Zahl, z. B. {‘$gt:0’};

Die resultierende Abfrage lautet:

db.collections(“students”).find({age:{‘$gt:0’}); Dies ist eine gültige Abfrage, die bei der Ausführung alle Schüler in dieser Sammlung zurückgibt. Der Angreifer hat die Möglichkeit, gemäß seinen böswilligen Absichten auf Ihre Daten einzuwirken. In den meisten Fällen fügt ein Angreifer ein benutzerdefiniertes Objekt ein, das MongoDB-Befehle enthält, die es ihm ermöglichen, ohne das richtige Verfahren auf Ihre Dokumente zuzugreifen.

Einige MongoDB-Befehle führen Javascript-Code innerhalb der Datenbank-Engine aus, ein potenzielles Risiko für Ihre Daten. Einige dieser Befehle sind „$where“, „$group“ und „mapReduce“. Bei Versionen vor MongoDB 2.4 hat Js-Code Zugriff auf das db-Objekt innerhalb der Abfrage.

Naitive MongoDB-Schutzmaßnahmen

MongoDB verwendet die BSON-Daten (Binary JSON) sowohl für seine Abfragen als auch für Dokumente, aber in einigen Fällen kann es desialisierte JSON- und Js-Ausdrücke (wie die oben erwähnten) akzeptieren. Die meisten an den Server übergebenen Daten haben das Format einer Zeichenfolge und können direkt in eine MongoDB-Abfrage eingespeist werden. MongoDB analysiert seine Daten nicht und vermeidet daher potenzielle Risiken, die sich aus der Integration direkter Parameter ergeben können.

Wenn eine API die Codierung von Daten in einem formatierten Text beinhaltet und dieser Text geparst werden muss, besteht die Gefahr, dass zwischen dem Aufrufer des Servers und dem Aufgerufenen der Datenbank Meinungsverschiedenheiten darüber entstehen, wie diese Zeichenfolge geparst werden soll . Wenn die Daten versehentlich als Metadaten fehlinterpretiert werden, kann das Szenario möglicherweise Sicherheitsbedrohungen für Ihre Daten darstellen.

Beispiele für externe MongoDB-Injektionen und deren Handhabung

 Betrachten wir die folgenden Daten in einer Schülersammlung.

{username:'John Doc', password: ‘16djfhg’, email:'[email protected]', age:20},

{username:'Rafael Silver',password: ‘djh’, email:'[email protected]', age:30},

{username:'Kevin Smith', password: ‘16dj’, email:'[email protected]', age:22},

{username:'Pauline Wagu', password: ‘g6yj’, email:'[email protected]', age:23}

Injection mit dem Operator $ne (ungleich)

Wenn ich das Dokument mit Benutzername und Passwort aus einer Anfrage zurücksenden möchte, lautet der Code:

app.post('/students, function (req, res) {

    var query = {

        username: req.body.username,

        password: req.body.password

    }

    db.collection(students).findOne(query, function (err, student) {

        res(student);

    });

});

Wenn wir die nachstehende Anfrage erhalten

POST https://localhost/students HTTP/1.1

Content-Type: application/json

{

    "username": {"$ne": null},

    "password": {"$ne": null}

}

Die Abfrage wird in diesem Fall definitiv den ersten Studenten zurückgeben, da sein Benutzername und sein Passwort nicht als Null gewertet werden. Dies entspricht nicht den erwarteten Ergebnissen.

Um dies zu lösen, können Sie Folgendes verwenden:

mongo-sanitize-Modul, das verhindert, dass Schlüssel, die mit „$“ beginnen, an die MongoDB-Abfrage-Engine übergeben werden.

Installieren Sie zuerst das Modul  

​npm install mongo-sanitize

var sanitize = require(‘mongo-sanitize’);

var query = {

username: req.body.username,

password: req.body.password

}

Verwendung von Mongoose zur Validierung Ihrer Schemafelder, sodass die Abfrage einen Fehler auslöst, wenn sie eine Zeichenfolge erwartet und ein Objekt empfängt. In unserem obigen Fall wird der Nullwert in eine Zeichenfolge „“ konvertiert, die buchstäblich keine Auswirkung hat.

Injection mit dem $where-Operator

Dies ist einer der gefährlichsten Operatoren. Dadurch kann eine Zeichenfolge innerhalb des Servers selbst ausgewertet werden. Um beispielsweise Schüler abzurufen, deren Alter über dem Wert Y liegt, lautet die Abfrage 

var query = { 

   $where: “this.age > ”+req.body.age

}

 db.collection(students).findOne(query, function (err, student) {

        res(student);

    });

Die Verwendung des Sanitize-Moduls hilft in diesem Fall nicht, wenn wir eine '0; return true“, da das Ergebnis alle Schüler zurückgibt und nicht diejenigen, deren Alter größer als ein bestimmter Wert ist. Andere mögliche Zeichenfolgen, die Sie erhalten können, sind „\“; return \ ‘\’ ==\’’ oder  this.email ===‘’;return ‘’ ==‘’. Diese Abfrage gibt alle Schüler zurück und nicht nur diejenigen, die mit der Klausel übereinstimmen.

Die $where-Klausel sollte unbedingt vermieden werden. Neben dem skizzierten Nachteil verringert es auch die Leistung, da es nicht für die Verwendung von Indizes optimiert ist.

Es besteht auch die Möglichkeit, eine Funktion in der $where-Klausel zu übergeben, und auf die Variable kann im MongoDB-Bereich nicht zugegriffen werden, was zum Absturz Ihrer Anwendung führen kann. Dh

var query = {

   $where: function() {

       return this.age > setValue //setValue is not defined

   }

}

Sie können stattdessen auch die Operatoren $eq, $lt, $lte, $gt, $gte verwenden.

Sich vor MongoDB External Injection schützen

Hier sind drei Dinge, die Sie tun können, um sich zu schützen...

  1. Benutzerdaten validieren. Rückblickend darauf, wie der $where-Ausdruck verwendet werden kann, um auf Ihre Daten zuzugreifen, ist es ratsam, immer zu validieren, was Benutzer an Ihren Server senden.
  2. Verwenden Sie das JSON-Validierungskonzept, um Ihr Schema zusammen mit dem Mongoose-Modul zu validieren.
  3. Entwerfen Sie Ihre Abfragen so, dass Js-Code keinen vollständigen Zugriff auf Ihren Datenbankcode hat.

Fazit

Auch externe Injektionen sind mit MongoDB möglich. Es wird oft damit in Verbindung gebracht, dass nicht validierte Benutzerdaten in MongoDB-Abfragen gelangen. Es ist immer wichtig, NoSQL-Einschleusungen zu erkennen und zu verhindern, indem Sie alle Daten testen, die möglicherweise von Ihrem Server empfangen werden. Bei Vernachlässigung kann dies die Sicherheit der Benutzerdaten gefährden. Das wichtigste Verfahren besteht darin, Ihre Daten auf allen beteiligten Ebenen zu validieren.