Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо
to the top
close form

Заполните форму в два простых шага ниже:

Ваши контактные данные:

Шаг 1
Поздравляем! У вас есть промокод!

Тип желаемой лицензии:

Шаг 2
Team license
Enterprise license
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности
close form
Запросите информацию о ценах
Новая лицензия
Продление лицензии
--Выберите валюту--
USD
EUR
RUB
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Бесплатная лицензия PVS‑Studio для специалистов Microsoft MVP
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Для получения лицензии для вашего открытого
проекта заполните, пожалуйста, эту форму
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Мне интересно попробовать плагин на:
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
check circle
Ваше сообщение отправлено.

Мы ответим вам на


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

  • Промоакции
  • Оповещения
  • Спам

>
>
>
V5622. OWASP. Possible XPath injection.…
menu mobile close menu
Проверка проектов
Сообщения PVS-Studio
Диагностики общего назначения (General Analysis, C++)
Диагностики общего назначения (General Analysis, C#)
Диагностики общего назначения (General Analysis, Java)
Микрооптимизации (C++)
Диагностика 64-битных ошибок (Viva64, C++)
Реализовано по запросам пользователей (C++)
Cтандарт MISRA
Стандарт AUTOSAR
Стандарт OWASP (C++)
Стандарт OWASP (C#)
Проблемы при работе анализатора кода
Дополнительная информация
toggle menu Оглавление

V5622. OWASP. Possible XPath injection. Potentially tainted data is used in the XPath expression.

11 Май 2022

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

Уязвимости, связанные с инъекциями, относятся к категории A03:2021 – Injection списка OWASP Top 10 Application Security Risks.

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

class UserData
{
  HttpRequest request;
  XPathNavigator navigator;

  void RetrieveUserData()
  {
    string username = request.Form["username"];
    string password = request.Form["password"];
    string hashedPassword = Hash(password);
    
    string query = $@"//users/user[
                      username/text() = '{username}' and
                      passwordHash/text() = '{hashedPassword}']
                      /data/text()";
    
    object res = navigator.Evaluate(query);
    ....
  }
}

В этом примере XPath-выражение используется для получения данных пользователя из XML-файла. Имя пользователя хранится "как есть", а пароль хранится в зашифрованном виде.

Злоумышленник может передать в качестве имени пользователя и пароля любые данные. Проверка будет скомпрометирована, если во входных данных передать выражение, которое сделает XPath-условие всегда истинным. Так как пароль хранится в зашифрованном виде, то внедрять опасное выражение нужно вместе с именем пользователя.

Для примера пусть имя пользователя будет 'john'. Добавим к нему выражение такого вида:

' or ''='

Вместо пароля может быть введён любой набор символов. Тогда XPath-выражение будет иметь такой вид:

[
  username/text()='john' or ''='' and
  passwordHash/text() = '750084105bcbe9d2c89ba9b'
]

Теперь выражение содержит оператор 'or'. Рассмотрим, как оно вычисляется:

  • Так как имя пользователя существует, выражение "username/text()='john'" является истинным.
  • В качестве пароля были введены случайные символы, поэтому выражение passwordHash/text() = '750084105bcbe9d2c89ba9b' является ложным.
  • Выражение ''='' всегда истинно.
  • Приоритет оператора 'and' выше, чем 'or', поэтому происходит вычисление выражения ''='' and passwordHash/text() = '750084105bcbe9d2c89ba9b'. Результатом является ложь.
  • Последним выполняется оператор 'or'. Выражение "username/text()='john' or false" является истинным. Следовательно, всё условие является истинным.

Таким образом, результатом XPath-запроса будут данные пользователя 'john' независимо от того, правильный пароль был введён или нет. Это может привести к утечке данных.

Не следует использовать непроверенные внешние данные в XPath-выражениях. Для повышения безопасности стоит экранировать потенциально опасные символы во внешних данных. Примерами таких символов являются "<", ">" и "'". Экранирование может быть произведено с помощью метода 'SecurityElement.Escape':

class UserData
{
  HttpRequest request;
  XPathNavigator navigator;
  void RetrieveUserData()
  {
    string username = request.Form["username"];
    string password = request.Form["password"];
    username = SecurityElement.Escape(username);
    string hashedPassword = Hash(password);
    string query = $@"//users/user[
                      username/text()= '{username}' and 
                      passwordHash/text() ='{hashedPassword}']
                      /data/text()";
    
    object res = navigator.Evaluate(query);
    ....
  }
}

Существуют другие возможности для предотвращения XPath-инъекций. Например, Microsoft предлагает возможность реализации класса-резолвера. Его можно использовать в методах класса 'XPathNavigator', которые принимают строку XPath-выражения и объект, реализующий интерфейс 'IXmlNamespaceResolver'.

Это позволяет определить свои собственные переменные и функции внутри XPath-выражения, которые будут обработаны резолвером. Само по себе это не является решением проблемы XPath-инъекции, но определение своиx переменных позволяет использовать подход, похожий на параметризацию SQL-запросов.

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

public class UserData
{
  XPathNavigator navigator;
  public object RetrieveUserData(string username,
                                 string password)
  {
    string hashedPassword = Hash(password);
    string query = $@"//users/user[
                     username/text()= '{username}' and 
                     passwordHash/text() = '{hashedPassword}']
                     /data/text()";
    
    return EvaluateXpath(query);
  }
  
  private object EvaluateXpath(string xpath)
  {
    object res = navigator.Evaluate(xpath);
    ....
  }
}

В этом примере метод 'RetrieveUserData' доступен из других сборок. Параметры этого метода 'username' и 'password' не проверяются перед внедрением в XPath-запрос. Полученное выражение в переменной 'query' передаётся в метод 'EvaluateXpath', где используется без проверки. В таком случае анализатор выдаст предупреждение с низким уровнем достоверности.

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

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