sql >> Database teknologi >  >> NoSQL >> MongoDB

Sikring af MongoDB mod eksterne injektionsangreb

MongoDB-sikkerhed er ikke fuldt ud garanteret ved blot at konfigurere autentificeringscertifikater eller kryptere dataene. Nogle angribere vil "gå den ekstra mil" ved at lege med de modtagne parametre i HTTP-anmodninger, som bruges som en del af databasens forespørgselsproces.

SQL-databaser er de mest sårbare over for denne type angreb, men ekstern indsprøjtning er også mulig i NoSQL DBM'er såsom MongoDB. I de fleste tilfælde sker eksterne injektioner som et resultat af en usikker sammenkædning af strenge, når der oprettes forespørgsler.

Hvad er et eksternt injektionsangreb?

Kodeinjektion er dybest set at integrere uvaliderede data (ubegrænset vektor) i et sårbart program, som når det udføres, fører til katastrofal adgang til din database; truer dens sikkerhed.

Når usanitiserede variabler overføres til en MongoDB-forespørgsel, bryder de dokumentforespørgselsorienteringsstrukturen og udføres nogle gange som selve javascript-koden. Dette er ofte tilfældet, når rekvisitter sendes direkte fra body-parser-modulet til Nodejs-serveren. Derfor kan en angriber nemt indsætte et Js-objekt, hvor du ville forvente en streng eller et tal, og derved få uønskede resultater eller ved at manipulere dine data.

Overvej nedenstående data i en elevs samling.

{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}

Lad os sige, at dit program skal hente alle elever, hvis alder er lig med 20, du ville skrive en kode som denne...

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

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

})

Du vil have indsendt et JSON-objekt i din http-anmodning som 

{age: 20}

Dette vil returnere alle elever, hvis alder er lig med 20 år, som det forventede resultat og i dette tilfælde kun {brugernavn:'John Doc', email:'[email protected]', age:20} .

Lad os nu sige, at en angriber indsender et objekt i stedet for et tal, dvs. {‘$gt:0’};

Den resulterende forespørgsel vil være:

db.collections(“studerende”).find({alder:{‘$gt:0’}); som er en gyldig forespørgsel, der ved udførelse returnerer alle elever i den pågældende samling. Angriberen har en chance for at handle på dine data i overensstemmelse med deres ondsindede hensigter. I de fleste tilfælde injicerer en angriber et brugerdefineret objekt, der indeholder MongoDB-kommandoer, der sætter dem i stand til at få adgang til dine dokumenter uden den korrekte procedure.

Nogle MongoDB-kommandoer udfører Javascript-kode i databasemotoren, hvilket er en potentiel risiko for dine data. Nogle af disse kommandoer er '$where', '$group' og 'mapReduce'. For versioner før MongoDB 2.4 har Js-kode adgang til db-objektet fra forespørgslen.

MongoDB Naitive beskyttelser

MongoDB bruger BSON-dataene (binær JSON) til både dets forespørgsler og dokumenter, men i nogle tilfælde kan den acceptere userialiserede JSON- og Js-udtryk (såsom dem, der er nævnt ovenfor). De fleste af de data, der sendes til serveren, er i formatet som en streng og kan føres direkte ind i en MongoDB-forespørgsel. MongoDB analyserer ikke sine data og undgår derfor potentielle risici, der kan følge af, at direkte parametre integreres.

Hvis en API involverer kodning af data i en formateret tekst, og den tekst skal parses, har det potentiale til at skabe uenighed mellem serverens kaldende og databasens kaldende om, hvordan den streng skal analyseres . Hvis data ved et uheld misfortolkes som metadata, kan scenariet potentielt udgøre sikkerhedstrusler mod dine data.

Eksempler på MongoDB eksterne injektioner og hvordan man håndterer dem

 Lad os overveje dataene nedenfor i en elevsamling.

{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}

Injektion ved hjælp af $ne (ikke lige) operatør

Hvis jeg ønsker at returnere dokumentet med brugernavn og adgangskode fra en anmodning, vil koden være:

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);

    });

});

Hvis vi modtager anmodningen nedenfor

POST https://localhost/students HTTP/1.1

Content-Type: application/json

{

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

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

}

Forespørgslen vil helt sikkert returnere den første elev i dette tilfælde, da hans brugernavn og adgangskode ikke vurderes til at være null. Dette er ikke i overensstemmelse med de forventede resultater.

For at løse dette kan du bruge:

mongo-sanitize-modul, som forhindrer enhver nøgle, der starter med '$', i at blive sendt til MongoDB-forespørgselsmotoren.

Installer modulet først  

​npm install mongo-sanitize

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

var query = {

username: req.body.username,

password: req.body.password

}

Brug af mongoose til at validere dine skemafelter, således at hvis den forventer en streng og modtager et objekt, vil forespørgslen give en fejl. I vores tilfælde ovenfor vil null-værdien blive konverteret til en streng "", som bogstaveligt talt ikke har nogen indflydelse.

Injektion ved hjælp af $where-operatøren

Dette er en af ​​de farligste operatører. Det vil tillade en streng at blive evalueret inde i selve serveren. For f.eks. at hente elever, hvis alder er over en værdi Y, vil forespørgslen være 

var query = { 

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

}

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

        res(student);

    });

Brug af sanitize-modulet hjælper ikke i dette tilfælde, hvis vi har en '0; return true', fordi resultatet vil returnere alle elever i stedet for dem, hvis alder er større end en given værdi. Andre mulige strenge du kan modtage er '\'; returner \ '\' ==\'' eller  this.email ===''; returner '' ==''. Denne forespørgsel vil returnere alle elever i stedet for kun dem, der matcher klausulen.

$where-sætningen bør i høj grad undgås. Udover det skitserede tilbageslag reducerer det også ydeevnen, fordi det ikke er optimeret til at bruge indekser.

Der er også en stor mulighed for at sende en funktion i $where-sætningen, og variablen vil ikke være tilgængelig i MongoDB-omfanget, og kan derfor resultere i, at din applikation går ned. Dvs.

var query = {

   $where: function() {

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

   }

}

Du kan også bruge operatorerne $eq, $lt, $lte, $gt, $gte i stedet.

Beskyt dig selv mod MongoDB ekstern injektion

Her er tre ting, du kan gøre for at beskytte dig selv...

  1. Valider brugerdata. Når man ser tilbage på, hvordan udtrykket $where kan bruges til at få adgang til dine data, er det tilrådeligt altid at validere, hvad brugere sender til din server.
  2. Brug JSON-valideringskonceptet til at validere dit skema sammen med mongoose-modulet.
  3. Design dine forespørgsler sådan, at Js-kode ikke har fuld adgang til din databasekode.

Konklusion

Ekstern injektion er også mulig med MongoDB. Det er ofte forbundet med uvaliderede brugerdata, der kommer ind i MongoDB-forespørgsler. Det er altid vigtigt at opdage og forhindre NoSQL-injektion ved at teste alle data, der kan modtages af din server. Hvis det forsømmes, kan dette true sikkerheden af ​​brugerdata. Den vigtigste procedure er at validere dine data på alle involverede lag.


  1. Hvordan forespørger man MongoDB for at teste, om en vare eksisterer?

  2. ved at bruge Async i en transaktion i Spring-applikationen

  3. Spring Redis sorteringsnøgler

  4. Forespørgsel på indlejrede objekter i Mongoid/rails 3 (lavere end, min-operatorer og sortering)