MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Защита на MongoDB от външни атаки с инжектиране

Сигурността на MongoDB не е напълно гарантирана чрез просто конфигуриране на удостоверения за удостоверяване или криптиране на данните. Някои нападатели ще „извършат допълнителната миля“, като си играят с получените параметри в HTTP заявки, които се използват като част от процеса на заявка на базата данни.

SQL бази данни са най-уязвими към този тип атаки, но външно инжектиране е възможно и в NoSQL DBM, като MongoDB. В повечето случаи външните инжекции се случват в резултат на опасна конкатенация на низове при създаване на заявки.

Какво е външно инжектиране?

Инжектирането на код е основно интегриране на невалидирани данни (неограничен вектор) в уязвима програма, която, когато бъде изпълнена, води до катастрофален достъп до вашата база данни; застрашавайки неговата безопасност.

Когато неочистените променливи се предават в заявка на MongoDB, те нарушават структурата на ориентацията на заявката за документ и понякога се изпълняват като самия javascript код. Това често се случва при предаване на реквизити директно от модула body-parser за сървъра на Nodejs. Следователно, нападателят може лесно да вмъкне Js обект там, където бихте очаквали низ или число, като по този начин получи нежелани резултати или като манипулира вашите данни.

Разгледайте данните по-долу в колекцията на ученик.

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

Да приемем, че програмата ви трябва да извлече всички студенти, чиято възраст е равна на 20,  ще напишете код като този...

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

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

})

Ще сте изпратили JSON обект във вашата http заявка като 

{age: 20}

Това ще върне всички ученици, чиято възраст е равна на 20, като очаквания резултат и в този случай само {username:'John Doc', email:'[email protected]', age:20} .

Сега да кажем, че нападателят изпраща обект вместо число, т.е. {‘$gt:0’};

Резултантната заявка ще бъде:

db.collections(“студенти”).find({age:{‘$gt:0’}); което е валидна заявка, която при изпълнение  ще върне всички ученици в тази колекция. Нападателят има шанс да действа с вашите данни според своите злонамерени намерения. В повечето случаи нападателят инжектира персонализиран обект, който съдържа команди MongoDB, които им позволяват достъп до вашите документи без правилната процедура.

Някои команди на MongoDB изпълняват Javascript код в рамките на двигателя на базата данни, което представлява потенциален риск за вашите данни. Някои от тези команди са „$where“, „$group“ и „mapReduce“. За версии преди MongoDB 2.4, Js кодът има достъп до обекта db от заявката.

Нативни защити на MongoDB

MongoDB използва BSON данните (Binary JSON) както за своите заявки, така и за документи, но в някои случаи може да приеме несериализирани JSON и Js изрази (като споменатите по-горе). Повечето от данните, предавани на сървъра, са във формат на низ и могат да се подават директно в заявка на MongoDB. MongoDB не анализира своите данни, като по този начин избягва потенциални рискове, които могат да възникнат от интегрирането на директни параметри.

Ако API включва кодиране на данни във форматиран текст и този текст трябва да бъде анализиран, той има потенциала да създаде разногласия между обаждащия се на сървъра и обаждащия се на базата данни за това как този низ ще бъде анализиран . Ако данните бъдат случайно погрешно интерпретирани като метаданни, сценарият може потенциално да представлява заплаха за сигурността на данните ви.

Примери за външни инжекции на MongoDB и как да се справяте с тях

 Нека разгледаме данните по-долу в колекция от ученици.

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

Инжектиране с помощта на $ne (not equal) оператор

Ако искам да върна документа с потребителско име и парола, предоставени от заявка, кодът ще бъде:

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

    });

});

Ако получим заявката по-долу

POST https://localhost/students HTTP/1.1

Content-Type: application/json

{

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

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

}

Заявката определено ще върне първия ученик в този случай, тъй като неговото потребителско име и парола не се оценяват като нулеви. Това не е според очакваните резултати.

За да разрешите това, можете да използвате:

mongo-sanitize модул, който спира предаването на всеки ключ, който започва с „$“ в системата за заявки на MongoDB.

Първо инсталирайте модула  

​npm install mongo-sanitize

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

var query = {

username: req.body.username,

password: req.body.password

}

Използване на mongoose за валидиране на полетата на вашата схема, така че ако очаква низ и получи обект, заявката ще изведе грешка. В нашия случай по-горе стойността null ще бъде преобразувана в низ „“, който буквално няма влияние.

Инжектиране с помощта на $where оператор

Това е един от най-опасните оператори. Това ще позволи на низ да бъде оценен вътре в самия сървър. Например, за да извлечете ученици, чиято възраст е над стойност Y, заявката ще бъде 

var query = { 

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

}

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

        res(student);

    });

Използването на модула sanitize няма да помогне в този случай, ако имаме „0; return true“, защото резултатът ще върне всички ученици, а не тези, чиято възраст е по-голяма от дадена стойност. Други възможни низове, които можете да получите, са „\“; return \ ‘\’ ==\’’ или  this.email ===‘’;return ‘’ ==‘’. Тази заявка ще върне всички ученици, а не само тези, които отговарят на клаузата.

Клаузата $where трябва да се избягва значително. Освен очертания спад, той също намалява производителността, тъй като не е оптимизиран за използване на индекси.

Също така има голяма възможност за предаване на функция в клаузата $where и променливата няма да бъде достъпна в обхвата на MongoDB, следователно може да доведе до срив на приложението ви. т.е.

var query = {

   $where: function() {

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

   }

}

Вместо това можете да използвате и операторите $eq, $lt, $lte, $gt, $gte.

Да се ​​предпазите от външно инжектиране на MongoDB

Ето три неща, които можете да направите, за да се защитите...

  1. Проверете потребителските данни. Поглеждайки назад как изразът $where може да се използва за достъп до вашите данни, препоръчително е винаги да проверявате това, което потребителите изпращат на вашия сървър.
  2. Използвайте концепцията за валидиране на JSON, за да потвърдите вашата схема заедно с модула mongoose.
  3. Оформете заявките си така, че Js кодът да няма пълен достъп до кода на вашата база данни.

Заключение

Външно инжектиране също е възможно с MongoDB. Често се свързва с невалидирани потребителски данни, влизащи в заявки на MongoDB. Винаги е важно да откривате и предотвратявате инжектирането на NoSQL чрез тестване на всички данни, които могат да бъдат получени от вашия сървър. Ако се пренебрегне, това може да застраши безопасността на потребителските данни. Най-важната процедура е да потвърдите данните си на всички участващи слоеве.


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Node.js - Mongoose - Проверете дали съществува колекция

  2. Как да намерите неизползвани индекси в MongoDB?

  3. Достъп до MongoDB от Go

  4. Как мога да направя заявка за mongodb с помощта на mongoid/rails без изтичане на времето?

  5. Как лесно да управлявате актуализации на база данни и корекции за сигурност