Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо
to the top
>
>
>
V5312. OWASP. Possible XPath injection.…
menu mobile close menu
Проверка проектов
Интеграция результатов анализа PVS-Studio в инструменты контроля качества кода (веб дашборд)
Сообщения 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 Оглавление

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

04 Фев 2025

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

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

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

public class UserData {
    HttpServletRequest request;
    MessageDigest digest;
    Document doc;

    public void retrieveUserData() {
        String user = request.getParameter("username");
        String password = request.getParameter("password");
        String passwordHash = Arrays.toString(
                digest.digest(password.getBytes(StandardCharsets.UTF_8))
        );
        var xpath = XPathFactory.newInstance().newXPath();

        String query = "//users/user[" +
                "username/text() = '%s' and" +
                "passwordHash/text() = '%s']" +
                "/data/text()";
        query = String.format(query, user, passwordHash);

        try {
            String result = xpath.evaluate(query, doc);
            // ....
        } catch (XPathExpressionException e) {
            // ....
        }
        //....
    }
}

В этом примере 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-выражениях. Для повышения безопасности стоит экранировать потенциально опасные символы во внешних данных. Примерами таких символов являются <, > и '. Экранирование может быть произведено с помощью простого replaceAll:

public class UserData {
    HttpServletRequest request;
    MessageDigest digest;
    Document doc;

    public void retrieveUserData() {
        String user = request.getParameter("username")
                .replaceAll("'", "&abos;");
        String password = request.getParameter("password");
        String passwordHash = Arrays.toString(
                digest.digest(password.getBytes(StandardCharsets.UTF_8))
        );
        var xpath = XPathFactory.newInstance().newXPath();

        String query = "//users/user[" +
                "username/text() = '%s' and" +
                "passwordHash/text() = '%s']" +
                "/data/text()";
        query = String.format(query, user, passwordHash);

        try {
            String result = xpath.evaluate(query, doc);
            // ....
        } catch (XPathExpressionException e) {
            // ....
        }
        //....
    }
}

Apache Commons Text также содержит класс утилит StringEscapeUtils, двумя методами которого являются escapeXml10 и escapeXml11. Эти методы позволят экранировать все необходимые символы.

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

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
Ваше сообщение отправлено.

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


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

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