
Библиотека Java для быстрой и настраиваемой очистки ненадёжного HTML для предотвращения межсайтового скриптинга (XSS). Использует сканирование на основе политик для санитизации предоставленной пользователем разметки.
Библиотека для быстрой настраиваемой очистки HTML, поступающего из ненадёжных источников. Поддерживает Java 7+.
Другими словами, это API, который помогает убедиться, что клиенты не вставляют вредоносный код в HTML, который они предоставляют для своего профиля, комментариев и т.д., и который сохраняется на сервере. Термин «вредоносный код» в веб-приложениях обычно означает JavaScript. В основном каскадные таблицы стилей считаются вредоносными только тогда, когда они вызывают JavaScript. Однако существует множество ситуаций, когда «обычный» HTML и CSS могут быть использованы во вред.
Сначала добавьте зависимость из Maven:
<dependency>
<groupId>org.owasp.antisamy</groupId>
<artifactId>antisamy</artifactId>
<version>LATEST_VERSION</version>
</dependency>
Вероятно, сценарий использования AntiSamy на вашем сайте хотя бы приблизительно соответствует одному из предопределённых файлов политик. Каждый из них представляет собой «типичный» сценарий разрешения пользователям предоставлять HTML (и, возможно, CSS) форматирование. Рассмотрим различные файлы политик:
Slashdot — это технический новостной сайт, который позволяет пользователям анонимно отвечать на новости с очень ограниченной HTML-разметкой. Slashdot — один из самых крутых сайтов, но также он подвергался множеству успешных атак. Правила Slashdot довольно строги: пользователи могут отправлять только следующие HTML-теги и никакого CSS: , , , , .
<b><u><i><a><blockquote>Соответственно, мы создали файл политики, который обеспечивает довольно похожую функциональность. Разрешены все теги форматирования текста, которые напрямую воздействуют на шрифт, цвет или выделение.
eBay — самый популярный сайт онлайн-аукционов во вселенной, насколько я могу судить. Это общедоступный сайт, поэтому каждый может размещать объявления с богатым HTML-содержимым. Неудивительно, что, учитывая привлекательность eBay как цели, он подвергался нескольким сложным XSS-атакам. Объявления могут содержать гораздо более богатый контент, чем, скажем, Slashdot, поэтому его поверхность атаки значительно больше.
MySpace был, на момент создания этого проекта, самым популярным сайтом социальной сети. Пользователям разрешалось отправлять практически любой HTML и CSS — при условии, что они не содержали JavaScript. MySpace использовал чёрный список слов для проверки HTML пользователей, из-за чего они подверглись печально известному червю Samy. Червь Samy, который использовал фрагментарные атаки в сочетании со словом, которое должно было быть в чёрном списке (eval), послужил вдохновением для этого проекта.
Я не знаю возможного сценария использования этого файла политики. Если вы хотите разрешить все допустимые элементы HTML и CSS (но без JavaScript или явных фишинговых атак, связанных с CSS), вы можете использовать этот файл политики. Даже MySpace не был настолько безумным. Однако он служит хорошим справочником, поскольку содержит базовые правила для каждого элемента, поэтому вы можете использовать его как базу знаний при настройке других файлов политик.
Во время работы над улучшениями определения схемы XML (XSD) для файлов политик AntiSamy мы заметили, что AntiSamy фактически НЕ применял XSD. Поэтому мы ИЗМЕНИЛИ поведение по умолчанию, начиная с AntiSamy 1.6.0, чтобы принудительно проверять схему и не продолжать работу, если политика AntiSamy недействительна. Однако ...
мы понимаем, что разработчики могут не иметь возможности сразу исправить свои политики AntiSamy, если они не соответствуют требованиям, но при этом хотят обновить AntiSamy, чтобы получить улучшения безопасности, расширения функциональности и исправления ошибок. В связи с этим мы предоставили два способа (временно!) отключить проверку схемы:
Установите системное свойство Java: owasp.validator.validateschema в false. Это можно сделать в командной строке (например, -Dowasp.validator.validateschema=false) или через файл системных свойств Java. Ни одно из этих действий не требует изменения кода.
Измените код, использующий AntiSamy, чтобы вызвать Policy.setSchemaValidation(false) до загрузки политики AntiSamy. Это статический вызов, поэтому, если он отключён один раз, он отключён для всех новых экземпляров Policy.
Чтобы побудить пользователей AntiSamy использовать только политики, соответствующие XSD, AntiSamy всегда будет выводить предупреждение, когда проверка схемы отключена. Он либо ПРЕДУПРЕДИТ, что политика не соответствует требованиям, чтобы её можно было исправить, либо ПРЕДУПРЕДИТ, что политика соответствует требованиям, но проверка схемы ВЫКЛЮЧЕНА, поэтому проверку следует снова включить (т.е. перестать её отключать). Мы также добавили ведение журнала на уровне INFO при загрузке и проверке схем AntiSamy.
Возможность отключить новую функцию проверки схемы предназначена как временная мера, чтобы облегчить переход к корректным файлам политик AntiSamy. Мы планируем отказаться от этой функции в следующем крупном выпуске. Мы предполагаем, что это произойдёт где-то в середине–конце 2022 года, так что не скоро. Идея состоит в том, чтобы дать командам разработчиков, использующим AntiSamy напрямую или через другие библиотеки, такие как ESAPI, достаточно времени, чтобы привести свои файлы политик в соответствие со схемой до того, как проверка схемы станет обязательной.
Это было быстро исправлено в 1.6.1, чтобы использовать только API slf4j. AntiSamy теперь включает библиотеку slf4j-simple для логирования, но пользователи AntiSamy могут импортировать и использовать альтернативную совместимую с slf4j библиотеку логирования, если они предпочитают. Они также могут исключить slf4j-simple, если захотят.
ПРЕДУПРЕЖДЕНИЕ: Использование AntiSamy slf4j-simple без файла конфигурации выводит сообщения в буферизованном виде в стандартный вывод. В результате некоторые или все эти сообщения могут быть потеряны, если возникнет исключение, например PolicyException. Это можно исправить, настроив slf4j-simple на вывод в стандартный поток ошибок или используя альтернативный регистратор slf4j, который это делает.
Возможно, вы захотите развернуть AntiSamy в конфигурации по умолчанию, но с такой же вероятностью сайт может захотеть иметь строгие, обусловленные бизнесом правила относительно того, что пользователи могут разрешить. Обсуждение, определяющее настройку, также должно учитывать поверхность атаки — она растёт пропорционально файлу политик.
Использовать AntiSamy легко. Вот пример вызова AntiSamy с файлом политик:
import org.owasp.validator.html.*;
Policy policy = Policy.getInstance(POLICY_FILE_LOCATION);
AntiSamy as = new AntiSamy();
CleanResults cr = as.scan(dirtyInput, policy);
MyUserDAO.storeUserProfile(cr.getCleanHTML()); // some custom function
Существует несколько способов создания объекта Policy. Метод getInstance() может принимать любой из следующих параметров:
StringFileInputStreamФайлы политик также могут быть указаны по имени файла путём передачи второго аргумента в метод AntiSamy#scan(), как показано в следующих примерах:
AntiSamy as = new AntiSamy();
CleanResults cr = as.scan(dirtyInput, policyFilePath);
Наконец, файлы политик также могут быть указаны непосредственно объектами File во втором параметре:
AntiSamy as = new AntiSamy();
CleanResults cr = as.scan(dirtyInput, new File(policyFilePath));
Объект CleanResults предоставляет много полезного.
getErrorMessages() — список строк с сообщениями об ошибках — если он возвращает 0, это не означает, что атак не было!getCleanHTML() — чистый, безопасный HTML-выводgetCleanXMLDocumentFragment() — чистый, безопасный XMLDocumentFragment, который отражён в getCleanHTML()getScanTime() — возвращает время сканирования в секундахВажное примечание: Метод getErrorMessages() часто вызывает путаницу. Метод getErrorMessages() не даёт тонкого ответа на вопрос «является ли этот ввод безопасным?» в утвердительном смысле, если возвращает пустой список. Вы всегда должны использовать санированный ввод, и нет никакого способа быть уверенным, что переданный ввод не содержал атак.
Процесс сериализации и десериализации, который является критически важным для эффективности санитайзера, намеренно является потерянным и будет отфильтровывать атаки через ряд векторов атак. К сожалению, одним из компромиссов этой стратегии является то, что мы не всегда знаем постфактум, что атака имела место. Таким образом, API getErrorMessages() существует для того, чтобы помочь пользователям понять, что их благонамеренный ввод соответствует требованиям системы, а не помочь разработчику обнаружить, присутствовала ли атака.
Дополнительную документацию можно найти на вики-странице этого проекта Github: https://github.com/nahsra/antisamy/wiki и на странице проекта OWASP AntiSamy: https://owasp.org/www-project-antisamy/
Если вы нашли ошибку, создайте issue в репозитории AntiSamy: https://github.com/nahsra/antisamy/issues
Если вы нашли уязвимость в AntiSamy, сначала проверьте список issues (см. выше), чтобы убедиться, что она ещё не была сообщена. Если нет, пожалуйста, свяжитесь напрямую с Дэйвом Уичерсом (dave.wichers at owasp.org). Пожалуйста, не сообщайте об уязвимостях через issues на GitHub, так как мы хотим обеспечить безопасность пользователей, пока исправление реализуется и развёртывается. Если вы хотите получить упоминание за обнаружение уязвимости, следуйте этому процессу.
Более подробная информация доступна в файле: SECURITY.md.
Вы можете легко собрать и протестировать из исходников:
$ git clone https://github.com/nahsra/antisamy
$ cd antisamy
$ mvn package
Выпущено под лицензией BSD-3-Clause, как указано здесь: LICENSE.