Для получения триального ключа
заполните форму ниже
Team License (базовая версия)
Enterprise License (расширенная версия)
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

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

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

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

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

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

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


Если вы так и не получили ответ, пожалуйста, проверьте папку
Spam/Junk и нажмите на письме кнопку "Не спам".
Так Вы не пропустите ответы от нашей команды.

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

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', где используется без проверки. В таком случае анализатор выдаст предупреждение с низким уровнем достоверности.

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

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