Unicorn with delicious cookie
Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо
to the top
>
>
>
V5627. OWASP. Possible NoSQL...
menu mobile close menu
Проверка проектов
Дополнительная информация
toggle menu Оглавление

V5627. OWASP. Possible NoSQL injection. Potentially tainted data is used to create query.

18 Окт 2022

Анализатор обнаружил использование непроверенных данных из внешнего источника для формирования запроса к NoSQL базе данных. Это может стать причиной NoSQL-инъекции в случае, если данные скомпрометированы.

Инъекции выделены в отдельную категорию рисков в OWASP Top 10 Application Security Risks 2021: A3:2021-Injection.

Рассмотрим пример:

public IFindFluent<BsonDocument, BsonDocument> Authentication()
{
  String log = Request.Form["login"];
  String pass = Request.Form["password"];
  String filter = "{$where: \"function() {" +
         $"return this.login=='{log}' && this.password=='{pass}'"+
     ";}\"}";
  return collection.Find(filter);
}

Метод 'Authentication' ищет запись пользователя в NoSQL базе данных MongoDB по логину и паролю. Для этого создается строка 'filter', содержащая JavaScript код. С её помощью будут фильтроваться результаты поиска. Аналогом этой операции в SQL будет следующий запрос: SELECT * FROM collection WHERE login = @log AND password = @pass.

Для формирования фильтра используются значения строк 'log' и 'pass', полученные из внешнего источника. Подобное использование непроверенных данных позволяет злоумышленнику внедрить вредоносный код внутрь запроса.

Например, здесь злоумышленник может отправить вместо ожидаемого значения 'pass' строку следующего вида:

"-1' || this.login == 'admin"

Тогда обращение к базе данных может выглядеть так:

{$where: "function() 
{ 
  return    this.login == 'doesn't matter'
         && this.password == '-1'
         || this.login == 'admin';
}"}

В таком случае запрос вернёт данные аккаунта администратора.

Для защиты от инъекций NoSQL базы предоставляют инструменты параметризированного создания запросов.

Пример создания безопасного запроса:

public IFindFluent<BsonDocument, BsonDocument> Authentication()
{
  String log = Request.Form["login"];
  String pass = Request.Form["password"];
  var filter =   Builders<BsonDocument>.Filter.Eq("login", log)
               & Builders<BsonDocument>.Filter.Eq("password", pass);
  return collection.Find(filter);
}

Здесь фильтр создается при помощи специального класса 'Builders'. За счёт этого запрос будет параметризованным и внешние данные не смогут повлиять на логику фильтрации.

Анализатор также считает источниками небезопасных данных параметры методов, доступных из других сборок. Более подробно эта тема раскрыта в заметке "Почему важно проверять значения параметров общедоступных методов".

Рассмотрим пример:

public class MongoDBRep
{
  public void DeleteItemsByCounter(string count)
  {
    DeleteMany(count);
  }

  private void DeleteMany(string count)
  {
    var filter = "{$where:\"function(){return this.count == "+count+";}\"}";
    collection.DeleteMany(filter);
  }
}

Здесь потенциально заражённые данные из параметра 'count' передаются в метод 'DeleteMany', внутри которого они без проверки используются для удаления записей из базы данных.

Злоумышленник может сформировать запрос следующего вида:

{$where: "function() 
{ 
  return    this.count == -999
         || 1 == 1;
}"}

Исполнение этого запроса приведёт к удалению всех документов базы данных, независимо от значения поля 'count'.

В этом случае рекомендуется защититься тем же способом, что был приведён ранее.

Выявляемые диагностикой ошибки классифицируются согласно ГОСТ Р 71207–2024 как критические и относятся к типу: Ошибки непроверенного использования чувствительных данных (ввода пользователя, файлов, сети и пр.).

Данная диагностика классифицируется как: