Последние методы защиты от XSS - Trusted Types и встроенный Sanitizer API
Обсуждая защиту от XSS, я упоминал необходимость обрабатывать пользовательский ввод. Если разрешен HTML, необходимо найти надежный пакет для его обработки.
Многие сайты имеют такие требования, поэтому браузеры постепенно начали предоставлять соответствующие функциональные возможности.
Создание новой функции с нуля обычно занимает долгое время, от предложения и спецификации до реализации, что может занять несколько лет. Темы Trusted Types и Sanitizer API, обсуждаемые в этой статье, в настоящее время поддерживаются только браузерами на основе Chromium. Они еще не официально поддерживаются в последних версиях Firefox (119) и Safari (17). Поэтому содержание этой статьи можно рассматривать как справочник для будущего использования в производстве, когда придет подходящее время.
Sanitizer API
Sanitizer API - это встроенный санитайзер, предоставляемый браузерами. Он довольно похож на ранее упомянутый DOMPurify с точки зрения использования. Вот пример:
Чтобы работать с Sanitizer API, был добавлен новый метод setHTML. Передавая исходный HTML и санитайзер, Sanitizer API может выполнять фильтрацию.
Отфильтрованный результат приведенного выше HTML:
Все опасные элементы удалены. Цель Sanitizer API - гарантировать, что "независимо от того, как вы его используете или настраиваете, XSS не произойдет". Это является как преимуществом, так и недостатком. Позвольте мне привести еще один пример, чтобы пояснить:
Файл конфигурации указывает, что разрешены iframes, включая атрибут src. Однако в итоговом результате iframe все равно удален. Это происходит потому что, как я упоминал ранее, Sanitizer API гарантирует, что вы никогда не сможете использовать опасные теги. Так что, независимо от конфигурации, iframes не разрешены.
Например, если применяется фильтрация к атрибуту src, следует ли фильтровать URL-ы внутри него? Следует ли удалить URL-ы data:? Что насчет srcdoc? Должен ли он также быть заново отфильтрован? Этот вопрос все еще открыт и неактивен уже более года.
Это можно считать как преимуществом, так и недостатком Sanitizer API. Хотя возможно ему недостаточно гибкости, его преимущество состоит в том, что, независимо от того, как он используется, проблем не будет. В отличие от сторонних пакетов, которые мы ранее представили, существует возможность проблем, если конфигурация не настроена должным образом.
В настоящее время Sanitizer API все еще находится на ранних стадиях разработки. Возможно, в будущем, когда все основные браузеры будут поддерживать Sanitizer API и он сможет достичь желаемых функций, можно будет рассмотреть возможность переключения на него.
Хотя я все еще рекомендую использовать DOMPurify для очистки, хорошо иметь представление о Sanitizer API.
Trusted Types
Trusted Types, как и Sanitizer API, тоже очень новый и в настоящее время поддерживается только браузерами на основе Chromium. Так что, на данный момент стоит просто ознакомиться с ним, поскольку он еще не дошел до зрелости.
При отображении пользовательских данных на фронтенде, мы должны постоянно контролировать, что пользовательский ввод правильно обрабатывается, чтобы предотвратить уязвимости XSS. Однако, во многих местах можно допустить ошибки, такие как innerHTML, <iframe srcdoc> или document.write и т.д. Если мы напрямую передаем необработанный ввод в них, это создает уязвимость XSS.
Помимо того, что разработчики должны быть осторожны при написании кода, есть ли другие методы для предотвращения проблем в этих местах? Например, предположим, я выполняю div.innerHTML = str, и если str - необработанная строка, он выдает ошибку и останавливает выполнение. Таким образом, можно уменьшить вероятность XSS.
Да, это то, что делает Trusted Types.
После добавления Trusted Types в CSP, можно включить Trusted Types для защиты этих DOM API, заставляя браузер пройти через обработку Trusted Types перед вставкой HTML:
Вот пример:
Вышеуказанный код при выполнении выдаст ошибку с следующим сообщением:
> This document requires 'TrustedHTML' assignment. Uncaught TypeError: Failed to set the 'innerHTML' property on 'Element': This document requires 'TrustedHTML' assignment.
После принудительной активации Trusted Types вы больше не сможете напрямую передавать строку в innerHTML. Вместо этого вам потребуется создать новую политику Trusted Types для обработки опасного HTML. Вот как это делается:
Цель Trusted Types - не "гарантировать, что ваш HTML не имеет проблем", а скорее "заставить использовать Trusted Types на потенциально проблемных DOM API и запретить использование строк". Это значительно снижает многие риски. Когда вы случайно забываете обработать пользовательский ввод, браузер выдает ошибку, а не обрабатывает необработанную строку как HTML.
Поэтому, после включения Trusted Types, вам нужно только сосредоточиться на реализации createHTML и убедиться, что эти реализации безопасны. Кроме того, из приведенного выше примера видно, что содержимое createHTML определяется нами, поэтому оно также может быть объединено с DOMPurify.
> Могу ли я использовать Sanitizer API вместе с Trusted Types?
> Да, пожалуйста. Мы видим в этих API решение разных аспектов одной и той же проблемы. Они отдельны, но должны хорошо работать вместе. Детали интеграции Santizer API/Trusted Types все еще вырабатываются.
Заключение
В этой статье мы рассмотрели два новых API: Sanitizer и Trusted Types. Эти API очень важны для безопасности фронтенда, поскольку они представляют собой активную поддержку браузеров для санитизации, позволяя разработчикам, иметь больше обороны против атак.
Last updated