Cross-Site Scripting уязвимость в Битрикс
Cross-Site Scripting (межсайтовый скриптинг) — это уязвимость, при которой злоумышленник может внедрить и выполнить вредоносный JavaScript-код на веб-странице. Если входные данные от пользователя не проходят проверку, скрипт получает возможность получить доступ к личной информации или изменить содержимое сайта.
Любые данные, вводимые через формы или поступающие из других источников, могут содержать опасные фрагменты кода.
При стандартной инсталляции платформы и использовании типовых решений, проблемы подобного рода практически не возникают.
Трудности обычно появляются только при внесении изменений и расширении функционала, особенно если разработка ведётся без учёта стандартных рекомендаций «1С-Битрикс» и пренебрегает требованиями безопасности.
Например,

Экранирование HTML-символов
Для замены специальных символов на соответствующие HTML-сущности рекомендуется применять следующие инструменты:
Функция `htmlspecialcharsbx` преобразует такие символы, как `<`, `>`, '', `&` в корректные HTML-коды.
Метод `\Bitrix\Main\Text\HtmlFilter::encode()` выполняет аналогичные операции и при этом поддерживает Unicode.
Не стоит использовать `htmlspecialcharsEx()`, поскольку она работает по принципу черного списка, ограничивая только конкретные символы.
Для более надежной защиты лучше применять либо полное экранирование через `htmlspecialcharsbx`,
либо использовать белые списки, например, с помощью `CBXSanitizer`.
Правильное экранирование данных в шаблонах
Чтобы предотвратить выполнение вредоносных скриптов, специальные символы в переменных необходимо экранировать. Например, так:
<!- Правильно: спецсимволы экранированы, скрипты не выполнятся ->
<?= \Bitrix\Main\Text\HtmlFilter::encode($foo) ?>
<!- Неправильно: если $foo содержит <sc ript>, он выполнится ->
<?= $foo ?>
В нашем случае делаем так
<?= \Bitrix\Main\Text\HtmlFilter::encode($_GET['sum']) ?>
Экранирование следует опускать только для тех данных, которым вы полностью доверяете, например, для строк, заданных непосредственно в исходном коде.
Экранирование в JavaScript
Функция `CUtil::JSEscape()` предназначена для корректного экранирования специальных символов JavaScript: кавычек `'` и `"`, обратного слэша `\`, а также переводов строки `\n` и `\r`.
Она подходит для обработки строк, которые будут заключены в кавычки.
// Корректное использование: строка обрамлена кавычками, спецсимволы экранированы
<script>
var foo = '<?= CUtil::JSEscape($foo) ?>';
</script>
// Некорректно: без кавычек результат воспринимается как код, а не строка
<script>
var foo = <?= CUtil::JSEscape($foo) ?>;
</script>
Таким образом, всегда оборачивайте результат в кавычки, чтобы избежать синтаксических ошибок и обеспечить безопасность исполнения.
Комбинированное экранирование
Рекомендуется применять двойное экранирование — сначала для JavaScript, затем для HTML — в следующих случаях:
- В обработчиках событий, таких как `onclick`, `onload` и аналогичных.
- В атрибутах, содержащих JavaScript-код, например, `href=«javascript:…»`.
- При генерации динамических скриптов в шаблонах.
<?php
// Сначала экранируем для JS, затем для HTML
$someData = CUtil::JSEscape($foo);
$someData = htmlspecialcharsbx($someData);
?>
<a href="#" onclick="doSome('<?= $someData ?>');">Click</a>
Работа с атрибутами в HTML
Для корректного использования атрибутов всегда оборачивайте их значения в двойные кавычки `"`.
Применение одинарных кавычек `' '` может привести к тому, что экранирование не сработает должным образом/
<!- Корректно: значения в двойных кавычках ->
<input type="text" name="foo" value="<?= htmlspecialcharsbx($fooValue) ?>" />
<!- ННекорректно: в одинарных кавычках экранирование может не сработать ->
<input type="text" name="foo" value='<?= htmlspecialcharsbx($fooValue) ?>' />
Работа с JSON
Если JSON не экранировать, в нём могут появиться закрывающие теги `</script>`, что приведёт к XSS-уязвимостям и внедрению вредоносного JavaScript-кода.
Функция `Json::encode` выполняет следующие задачи:
- Конвертирует данные в формат JSON
- Экранирует специальные символы
- Применяет Unicode-экранирование
<?php
// Массив с пользовательскими данными
$foo = ['key' => $userInput];
?>
<script>
// Безопасный вывод: </script> и другие спецсимволы экранированы
var foo = <?= Bitrix\Main\Web\Json::encode($foo) ?>;
</script>
Фильтрация HTML-кода
Если необходимо отобразить HTML, введённый пользователем, рекомендуется применять класс `CBXSanitizer`. Он удалит небезопасные теги и сохранит лишь разрешённые элементы.
Метод `sanitizeHtml()` выполняет очистку HTML-контента, обеспечивая безопасность вывода.
<div><?= (new CBXSanitizer)->sanitizeHtml($foo) ?></div>
В данном фрагменте используется класс `CBXSanitizer` для очистки данных, содержащихся в переменной `$foo`. Метод `sanitizeHtml` выполняет фильтрацию HTML-содержимого, предотвращая возможные уязвимости, связанные с внедрением вредоносного кода.
- Создаётся новый экземпляр класса `CBXSanitizer`.
- Метод `sanitizeHtml` вызывается с аргументом `$foo`.
- Результат работы выводится внутри тега `
Этот код обеспечивает безопасное отображение HTML, очищая входные данные перед выводом на страницу.
Таким образом, чтобы избежать подобных сложностей, важно придерживаться установленных правил и практик при доработках и интеграции новых модулей.
Чтобы избежать XSS-атак, необходимо всегда экранировать и фильтровать внешние данные перед их отображением в HTML или использовании в JavaScript.

Добавить комментарий