Смягчение атак с использованием 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 ответ
Хотя вы могли бы использовать $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() передается объекту, он изменяет исходный объект.