Смягчение атак с использованием MongoDB с помощью Mongoose

Я использую оболочку Mongoose ODM для NodeJS, и меня беспокоят инъекционные атаки. Предположим, у меня есть следующая схема:

const UserSchema = new mongoose.Schema({ userName: String, password: String });

Если бы я должен был выполнить запрос на вход в систему, который выглядит следующим образом:

router.post('/login', (request, response) => {

    const userName = request.body.userName;
    const password = request.body.password;

    User.findOne({ userName: userName }, function (error, user) {
        // ... check password, other logic
    });
});

Я был бы открыт для инъекционной атаки со следующей полезной нагрузкой JSON, которая всегда найдет пользователя:

{
    "email": { "$gte": "" },
    "password": { "$gte": "" }
}

Я не беспокоюсь о пароле, так как он хэшируется, если найден пользователь, который запрещает какой-либо фактический вход в систему, но я хочу убедиться, что мой ввод очищен, чтобы злоумышленник даже не достиг этого.

Мне известно о пакете NPM mongo-sanitize, указанном в аналогичном посте Stackru, который, по-видимому, удаляет все ключи JSON, начинающиеся с '$'. В любом случае я планирую использовать это, но никогда не позволю пользователю отправлять необработанный, необработанный JSON. Является ли хорошей практикой в ​​этом случае просто вызывать toString() для userName, предполагая, что я делаю правильно null чеки?

const userName = request.body.userName.toString();

Это исключит выполнение запроса, но он не будет чувствовать себя в безопасности. Я предполагаю, что следующий подход является лучшим подходом, поскольку он пытается преобразовать userName к String:

User.findOne({ userName: { "$eq": userName } }, function (error, user) {
     // ... other logic
});

Я не могу найти что-либо относительно этого в документации Model.findOne(), что наводит меня на мысль, что я что-то упускаю.

Любое понимание будет оценено.

Другие ссылки:

  1. https://blog.websecurify.com/2014/08/hacking-nodejs-and-mongodb.html
  2. https://ckarande.gitbooks.io/owasp-nodegoat-tutorial/content/tutorial/a1_-_sql_and_nosql_injection.html

1 ответ

Решение

Хотя вы могли бы использовать $eq чтобы в запросе использовалось сравнение на равенство, ваш обработчик экспресс-маршрутов является лучшим местом для проверки формата запроса.

Действительный POST /login должен иметь userName а также password строковые поля в теле запроса. Если нет, его следует отвергнуть еще до того, как он попадет в Мангуст.

Кроме того, вы можете использовать пакет npm " mongo-sanitize ", как указано в их документации, как показано ниже:

var sanitize = require('mongo-sanitize');

// The sanitize function will strip out any keys that start with '$' in the input,
// so you can pass it to MongoDB without worrying about malicious users overwriting
// query selectors.
var clean = sanitize(req.params.username);

Users.findOne({ name: clean }, function(err, doc) {
  // ...
});

Если sanitize() передается объекту, он изменяет исходный объект.

Другие вопросы по тегам