Назад к обновлениям
New releaseSep 22, 2026

java-html-sanitizer v20260921.1

Принимает HTML от третьих сторон и создаёт HTML, безопасный для встраивания в ваше веб-приложение. Быстро и легко настраивается.

Поделиться

OWASP Java HTML Sanitizer

Build OpenSSF Best Practices Maven Central

Быстрый и простой в настройке HTML-санитайзер, написанный на Java, который позволяет включать в ваше веб-приложение HTML-код, созданный третьими сторонами, обеспечивая при этом защиту от XSS.

JAR-файл санитайзера не имеет зависимостей времени выполнения. Его единственная зависимость времени компиляции — spotbugs-annotations (область provided, только аннотации); остальные jar-файлы нужны только для набора тестов.

Этот код написан с учётом лучших практик безопасности, имеет обширный набор тестов и прошёл состязательный аудит безопасности.

Содержание

Начало работы

Начало работы содержит инструкции о том, как начать работу с Maven или без него.

Структура репозитория

Для сборки требуется JDK 11 или новее. Из корня репозитория соберите все модули Maven и запустите их тесты с помощью:

./mvnw clean verify

Maven wrapper фиксирует требуемую версию Maven. Если вы выбираете модуль с помощью -pl, также используйте -am, чтобы Maven собрал модули, от которых он зависит.

  • owasp-java-html-sanitizer/ содержит публикуемую библиотеку, её тесты и её дескриптор модуля Java.
  • java8-shim/ и java10-shim/ реализуют код совместимости, который включается в JAR библиотеки.
  • examples/ содержит примеры политик для чтения и копирования; он тестируется, но не публикуется.
  • empiricism/ содержит браузерные эксперименты, использованные для генерации таблиц HTML-элементов санитайзера.
  • docs/ содержит пользовательскую, security- и историческую документацию.

Предустановленные политики

Вы можете использовать предустановленные политики:

PolicyFactory policy = Sanitizers.FORMATTING.and(Sanitizers.LINKS);
String safeHTML = policy.sanitize(untrustedHTML);

Создание политики

Тесты показывают, как настроить собственную политику:

PolicyFactory policy = new HtmlPolicyBuilder()
    .allowElements("a")
    .allowUrlProtocols("https")
    .allowAttributes("href").onElements("a")
    .requireRelNofollowOnLinks()
    .toFactory();
String safeHTML = policy.sanitize(untrustedHTML);

Пользовательские политики

Вы можете писать пользовательские политики, чтобы делать такие вещи, как замена h1 на div с определённым классом:

PolicyFactory policy = new HtmlPolicyBuilder()
    .allowElements("p")
    .allowElements(
        (String elementName, List<String> attrs) -> {
          // Add a class attribute.
          attrs.add("class");
          attrs.add("header-" + elementName);
          // Return elementName to include, null to drop.
          return "div";
        }, "h1", "h2", "h3", "h4", "h5", "h6")
    .toFactory();
String safeHTML = policy.sanitize(untrustedHTML);

Обратите внимание, что элементы "a", "font", "img", "input" и "span" необходимо явно добавить в белый список с помощью метода allowWithoutAttributes(), если вы хотите, чтобы они проходили через фильтр, когда эти элементы не содержат никаких атрибутов.

Политики атрибутов также позволяют запускать пользовательский код. Добавление политики атрибутов не ослабит никакую политику по умолчанию, например проверки атрибута style или URL-атрибутов.

PolicyFactory myPolicy = new HtmlPolicyBuilder()
    .allowElements("div", "span")
    .allowAttributes("data-foo")
        .matching(
            (String elementName, String attributeName, String value) -> {
              // Return value for the attribute or null to drop.
              return value;
            })
        .onElements("div", "span")
    .toFactory();

Препроцессоры

Препроцессоры позволяют вставлять текст и выполнять масштабные структурные изменения.

PolicyFactory myPolicy = new HtmlPolicyBuilder()
    .withPreprocessor(
        (HtmlStreamEventReceiver r) -> {
          // Provide user with info about links before they click.
          // Before:                       <a href="https://example.com/...">
          // After:  (https://example.com) <a href="https://example.com/...">
          return new HtmlStreamEventReceiverWrapper(r) {
            @Override public void openTag(String elementName, List<String> attrs) {
              if ("a".equals(elementName)) {
                for (int i = 0, n = attrs.size(); i < n; i += 2) {
                  if ("href".equals(attrs.get(i))) {
                    String url = attrs.get(i + 1);
                    String origin;
                    try {
                      URI uri = new URI(url);
                      String scheme = uri.getScheme();
                      String authority = uri.getRawAuthority();
                      if (scheme == null && authority == null) {
                        origin = null;
                      } else {
                        origin = (scheme != null ? scheme + ":" : "")
                               + (authority != null ? "//" + authority : "");
                      }
                    } catch (URISyntaxException ex) {
                      origin = "about:invalid";
                    }
                    if (origin != null) {
                      text(" (" + origin + ") ");
                    }
                  }
                }
              }
              super.openTag(elementName, attrs);
            }
          };
        })
     .allowElements("a")
     .allowAttributes("href").onElements("a")
     .allowStandardUrlProtocols()
    ...
    .toFactory();

Предварительная обработка выполняется до применения политики, поэтому не может повлиять на безопасность выходных данных.

Телеметрия

Категории