Перейти к содержанию

html-sanitize: Модуль NGINX для санитации HTML 5 с разрешенными элементами, атрибутами и CSS

Установка на Debian/Ubuntu

Эти документы относятся к APT пакету nginx-module-html-sanitize, предоставляемому репозиторием GetPageSpeed Extras.

  1. Настройте APT репозиторий, как описано в настройке APT репозитория.
  2. Установите модуль:
sudo apt-get update
sudo apt-get install nginx-module-html-sanitize
Показать дистрибутивы и архитектуры
| Дистрибутив | Версия          | Компонент   | Архитектуры   |
|--------------|------------------|-------------|-----------------|
| debian       | bookworm         | main        | amd64           |
| debian       | bookworm-mainline| main        | amd64           |
| debian       | trixie           | main        | amd64           |
| debian       | trixie-mainline  | main        | amd64           |
| ubuntu       | focal            | main        | amd64           |
| ubuntu       | focal-mainline   | main        | amd64           |
| ubuntu       | jammy            | main        | amd64           |
| ubuntu       | jammy-mainline   | main        | amd64           |
| ubuntu       | noble            | main        | amd64           |
| ubuntu       | noble-mainline   | main        | amd64           |

Название

ngx_http_html_sanitize_module - Основан на gumbo-parser от Google как парсер HTML5 и katana-parser от hackers-painters как парсер встроенного CSS для санитации HTML с разрешенными элементами, атрибутах и стилях CSS.

Статус

Готов к производству :-)

Пример

Пример конфигурации nginx в соответствии с https://dev.w3.org/html5/html-author/#the-elements:

server {
    listen 8888;

    location = /sanitize {
        # Явно установить кодировку utf-8
        add_header Content-Type "text/html; charset=UTF-8";

        client_body_buffer_size 10M;
        client_max_body_size 10M;

        html_sanitize on;

        # Проверьте https://dev.w3.org/html5/html-author/#the-elements

        # Корневой элемент
        html_sanitize_element html;

        # Метаданные документа
        html_sanitize_element head title base link meta style;

        # Скрипты
        html_sanitize_element script noscript;

        # Секции
        html_sanitize_element body section nav article aside h1 h2 h3 h4 h5 h6 header footer address;

        # Группировка содержимого
        html_sanitize_element p hr br pre dialog blockquote ol ul li dl dt dd;

        # Семантика уровня текста
        html_sanitize_element a q cite em strong small mark dfn abbr time progress meter code var samp kbd sub sup span i b bdo ruby rt rp;

        # Изменения
        html_sanitize_element ins del;

        # Встраиваемое содержимое
        htlm_sanitize_element figure img iframe embed object param video audio source canvas map area;

        # Табличные данные
        html_sanitize_element table caption colgroup col tbody thead tfoot tr td th;

        # Формы
        html_sanitize_element form fieldset label input button select datalist optgroup option textarea output;

        # Интерактивные элементы
        html_sanitize_element details command bb menu;

        # Разные элементы
        html_sanitize_element legend div;

        html_sanitize_attribute *.style;
        html_sanitize_attribute a.href a.hreflang a.name a.rel;
        html_sanitize_attribute col.span col.width colgroup.span colgroup.width;
        html_sanitize_attribute data.value del.cite del.datetime;
        html_sanitize_attribute img.align img.alt img.border img.height img.src img.width;
        html_sanitize_attribute ins.cite ins.datetime li.value ol.reversed ol.start ol.type ul.type;
        html_sanitize_attribute table.align table.bgcolor table.border table.cellpadding table.cellspacing table.frame table.rules table.sortable table.summary table.width;
        html_sanitize_attribute td.abbr td.align td.axis td.colspan td.headers td.rowspan td.valign td.width;
        html_sanitize_attribute th.abbr th.align th.axis th.colspan th.rowspan th.scope th.sorted th.valign th.width;

        html_sanitize_style_property color font-size;

        html_sanitize_url_protocol http https tel;
        html_sanitize_url_domain *.google.com google.com;

        html_sanitize_iframe_url_protocol http https;
        html_sanitize_iframe_url_domain facebook.com *.facebook.com;
    }
}

Рекомендуется использовать следующую команду для санитации HTML5:

$ curl -X POST -d "<h1>Hello World </h1>" http://127.0.0.1:8888/sanitize?element=2&attribute=1&style_property=1&style_property_value=1&url_protocol=1&url_domain=0&iframe_url_protocol=1&iframe_url_domain=0

<h1>Hello World </h1>

Эта строка запроса element=2&attribute=1&style_property=1&style_property_value=1&url_protocol=1&url_domain=0&iframe_url_protocol=1&iframe_url_domain=0 следуеующая:

С помощью ngx_http_html_sanitize_module мы имеем возможность указать, следует ли выводить элементы HTML5, атрибуты и свойства встроенного CSS с помощью directive и querystring следующим образом:

разрешенные элементы

  • отключить элемент:

если мы не хотим выводить какой-либо элемент, мы можем сделать это следующим образом:

curl -X POST -d "<h1>h1</h1>" http://127.0.0.1:8888/sanitize?element=0
  • включить элемент:

если мы хотим вывести какой-либо элемент, мы можем сделать это следующим образом:

$ curl -X POST -d "<h1>h1</h1><h7>h7</h7>" http://127.0.0.1:8888/sanitize?element=1

<h1>h1</h1><h7>h7</h7>

  • включить разрешенный элемент:

если мы хотим вывести разрешенный элемент, мы можем сделать это следующим образом:

$ curl -X POST -d "<h1>h1</h1><h7>h7</h7>" http://127.0.0.1:8888/sanitize?element=1

<h1>h1</h1>

разрешенный атрибут

  • отключить атрибут:

если мы не хотим выводить какой-либо атрибут, мы можем сделать это следующим образом:

curl -X POST -d "<h1 ha=\"ha\">h1</h1>" "http://127.0.0.1:8888/sanitize?element=1&attribute=0"

<h1>h1</h1>
  • включить атрибут:

если мы хотим вывести какой-либо атрибут, мы можем сделать это следующим образом:

$ curl -X POST -d "<h1 ha=\"ha\">h1</h1>" "http://127.0.0.1:8888/sanitize?element=1&attribute=1"

<h1 ha="ha">h1</h1>

  • включить разрешенный атрибут:

если мы хотим вывести разрешенный элемент, мы можем сделать это следующим образом:

$ curl -X POST -d "<img src=\"/\" ha=\"ha\" />" "http://127.0.0.1:8888/sanitize?element=1&attribute=2"

<img src="/" />

разрешенное свойство стиля

  • отключить свойство стиля:

если мы не хотим выводить какое-либо свойство стиля, мы можем сделать это следующим образом:

## Это не выведет никакое свойство стиля
curl -X POST -d "<h1 style=\"color:red;\">h1</h1>" "http://127.0.0.1:8888/sanitize?element=1&attribute=1&style_property=0"

<h1>h1</h1>
  • включить свойство стиля:

если мы хотим вывести любое свойство стиля, мы можем сделать это следующим образом:

$ curl -X POST -d "<h1 style=\"color:red;text-align:center;\">h1</h1>" "http://127.0.0.1:8888/sanitize?element=1&attribute=1&style_property=1"

<h1 style="color:red;text-align:center">h1</h1>

  • включить разрешенное свойство стиля:

если мы хотим вывести разрешенное свойство стиля, мы можем сделать это следующим образом:

$ curl -X POST -d "<h1 style=\"color:red;text-align:center;\" >h1</h1>" "http://127.0.0.1:8888/sanitize?element=1&attribute=1&style_property=2"

<h1 style="color:red;">h1</h1>

Описание

В настоящее время реализация ngx_http_html_sanitize_module основана на gumbo-parser и katana-parser. Мы создаем комбинацию на его основе и запускаем ее на nginx как центральный веб-сервис, поддерживаемый профессиональными специалистами по безопасности с целью устранения языковых различий. Если мы хотим добиться более высокой производительности (здесь бенчмарк), рекомендуется написать библиотеку на языке уровня обертки над чистой C-библиотекой, чтобы преодолеть накладные расходы на сетевую передачу.

Бенчмарк

Тестирование с помощью wrk -s benchmarks/shot.lua -d 60s "http://127.0.0.1:8888" на Intel(R) Xeon(R) CPU E5-2630 v3 @ 2.40GHz и 64GB памяти

Название Размер Средняя задержка QPS
hacker_news.html 30KB 9.06ms 2921.82
baidu.html 76KB 13.41ms 1815.75
arabic_newspapers.html 78KB 16.58ms 1112.70
bbc.html 115KB 17.96ms 993.12
xinhua.html 323KB 33.37ms 275.39
google.html 336KB 26.78ms 351.54
yahoo.html 430KB 29.16ms 323.04
wikipedia.html 511KB 57.62ms 160.10
html5_spec.html 7.7MB 1.63s 2.00

Директива

html_sanitize

синтаксис: html_sanitize on | off

по умолчанию: html_sanitize on

контекст: location

Указывает, включен ли обработчик санитации HTML на контексте локейшн

html_sanitize_hash_max_size

синтаксис: html_sanitize_hash_max_size size

по умолчанию: html_sanitize_hash_max_size 2048

контекст: location

Устанавливает максимальный размер таблиц хешей элементов, атрибутов, стилей, протоколов URL, доменов URL, протоколов URL iframe, доменов URL iframe.

html_sanitize_hash_bucket_size

синтаксис: html_sanitize_hash_bucket_size size

по умолчанию: html_sanitize_hash_bucket_size 32|64|128

контекст: location

Устанавливает размер корзины для элементов, атрибутов, свойств стилей, протоколов URL, доменов URL, протоколов URL iframe, доменов URL iframe. Значение по умолчанию зависит от размера линии кэша процессора.

html_sanitize_element

синтаксис: html_sanitize_element element ...

по умолчанию: -

контекст: location

Установите разрешенные HTML5 элементы, когда включен режим разрешенных элементов, задав строку запроса element:

html_sanitize_element html head body;

html_sanitize_attribute

синтаксис: html_sanitize_attribute attribute ...

по умолчанию: -

контекст: location

Установите разрешенные HTML5 атрибуты, когда включен режим разрешенных элементов, задав строку запроса attribute:

html_sanitize_attribute a.href h1.class;

PS: формат атрибута должен совпадать с element.attribute и поддерживать *.attribute (приставка с "" ) и element.* (суффикс с "" )

html_sanitize_style_property

синтаксис: html_sanitize_style_property property ...

по умолчанию: -

контекст: location

Установите разрешенное свойство CSS, когда включен режим разрешенных элементов, задав строку запроса style_property:

html_sanitize_style_property color background-color;

html_sanitize_url_protocol

синтаксис: html_sanitize_url_protocol [protocol] ...

по умолчанию: -

контекст: location

Установите разрешенные протоколы URL в [linkable attribute], когда URL является абсолютным, а не относительным, и включите проверку протокола URL, задав строку запроса url_protocol:

html_sanitize_url_protocol http https tel;

html_sanitize_url_domain

синтаксис: html_sanitize_url_domain domain ...

по умолчанию: -

контекст: location

Установите разрешенные домены URL в [linkable attribute], когда URL является абсолютным, а не относительным, и включите проверку протокола URL и домена URL, задав строки запроса url_protocol и url_domain:

html_sanitize_url_domain *.google.com google.com;

html_sanitize_iframe_url_protocol

синтаксис: html_sanitize_iframe_url_protocol [protocol] ...

по умолчанию: -

контекст: location

То же самое, что и html_sanitize_url_protocol, но только для атрибута iframe.src

html_sanitize_iframe_url_protocol http https tel;

html_sanitize_iframe_url_domain

синтаксис: html_sanitize_iframe_url_domain [protocol] ...

по умолчанию: -

контекст: location

То же самое, что и html_sanitize_url_domain, но только для атрибута iframe.src

html_sanitize_iframe_url_domain *.facebook.com facebook.com;

linkable_attribute

Разрешенные атрибуты:

  • a.href
  • blockquote.cite
  • q.cite
  • del.cite
  • img.src
  • ins.cite
  • iframe.src
  • CSS URL функция

Querystring

Строка запроса из URL запроса используется для управления внутренними действиями ngx_http_html_sanitize_module.

document

значение: 0 или 1

по умолчанию: 0

контекст: querystring

Указывает, следует ли добавлять <!DOCTYPE> к телу ответа

html

значение: 0 или 1

по умолчанию: 0

контекст: querystring

Указывает, следует ли добавлять <html></html> к телу ответа

script

значение: 0 или 1

по умолчанию: 0

контекст: querystring

Указывает, разрешено ли использование <script></script>

style

значение: 0 или 1

по умолчанию: 0

контекст: querystring

Указывает, разрешено ли использование <style></style>

namespace

значение: 0, 1 или 2

по умолчанию: 0

контекст: querystring

Указывает режим gumbo-parser со следующими значениями:

  • GUMBO_NAMESPACE_HTML: 0
  • GUMBO_NAMESPACE_SVG: 1
  • GUMBO_NAMESPACE_MATHML: 2

context

значение: [0, 150)

по умолчанию: 38(GUMBO_TAG_DIV)

контекст: querystring

Указывает контекст gumbo-parser со значениями из этого файла tag_enum.h

element

значение: 0, 1, 2

по умолчанию: 0

контекст: querystring

Указывает режим вывода элемента со следующими значениями:

  • 0: не выводить элемент
  • 1: выводить все элементы
  • 2: выводить разрешенные элементы

attribute

значение: 0, 1, 2

по умолчанию: 0

контекст: querystring

Указывает режим вывода атрибута со следующими значениями:

  • 0: не выводить атрибуты
  • 1: выводить все атрибуты
  • 2: выводить разрешенные атрибуты

style_property

значение: 0, 1, 2

по умолчанию: 0

контекст: querystring

Указывает режим вывода CSS свойства со следующими значениями:

  • 0: не выводить CSS свойства
  • 1: выводить все CSS свойства
  • 2: выводить разрешенные CSS свойства

style_property_value

значение: 0, 1

по умолчанию: 0

контекст: querystring

Указывает режим вывода значения свойства CSS со следующими значениями:

  • 0: не проверять значение CSS свойства
  • 1: проверять значение CSS свойства для функции URL и функции expression от IE, чтобы избежать инъекций XSS

url_protocol

значение: 0, 1

по умолчанию: 0

контекст: querystring

Указывает, следует ли проверять протокол URL в linkable_attribute. Значение следующее:

  • 0: не проверять протокол URL
  • 1: выводить разрешенный протокол URL

url_domain

значение: 0, 1

по умолчанию: 0

контекст: querystring

Указывает, следует ли проверять домен URL в linkable_attribute, когда включена проверка url_protocol. Значение следующее:

  • 0: не проверять домен URL
  • 1: выводить разрешенный домен URL

iframe_url_protocol

значение: 0, 1

по умолчанию: 0

контекст: querystring

То же самое, что и url_protocol, но только для iframe.src

iframe_url_domain

значение: 0, 1

по умолчанию: 0

контекст: querystring

То же самое, что и url_domain, но только для iframe.src