html-sanitize: Módulo NGINX para sanitizar HTML 5 com elementos, atributos e CSS na lista de permissões
Instalação
Você pode instalar este módulo em qualquer distribuição baseada em RHEL, incluindo, mas não se limitando a:
- RedHat Enterprise Linux 7, 8, 9 e 10
- CentOS 7, 8, 9
- AlmaLinux 8, 9
- Rocky Linux 8, 9
- Amazon Linux 2 e Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-html-sanitize
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install nginx-module-html-sanitize
Ative o módulo adicionando o seguinte no topo de /etc/nginx/nginx.conf:
load_module modules/ngx_http_html_sanitize_module.so;
Este documento descreve o nginx-module-html-sanitize v0.2.6 lançado em 07 de março de 2026.
Exemplo
Há um exemplo de configuração do nginx de acordo com o https://dev.w3.org/html5/html-author/#the-elements como o seguinte:
server {
listen 8888;
location = /sanitize {
# Definir explicitamente a codificação utf-8
add_header Content-Type "text/html; charset=UTF-8";
client_body_buffer_size 10M;
client_max_body_size 10M;
html_sanitize on;
# Verifique https://dev.w3.org/html5/html-author/#the-elements
# Elemento Raiz
html_sanitize_element html;
# Metadados do Documento
html_sanitize_element head title base link meta style;
# Scripting
html_sanitize_element script noscript;
# Seções
html_sanitize_element body section nav article aside h1 h2 h3 h4 h5 h6 header footer address;
# Agrupamento de Conteúdo
html_sanitize_element p hr br pre dialog blockquote ol ul li dl dt dd;
# Semântica de Nível de Texto
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;
# Edições
html_sanitize_element ins del;
# Conteúdo Embutido
htlm_sanitize_element figure img iframe embed object param video audio source canvas map area;
# Dados Tabulares
html_sanitize_element table caption colgroup col tbody thead tfoot tr td th;
# Formulários
html_sanitize_element form fieldset label input button select datalist optgroup option textare output;
# Elementos Interativos
html_sanitize_element details command bb menu;
# Elementos Diversos
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.stasrt 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;
}
}
E é recomendado usar o comando abaixo para sanitizar 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>
Esta string de consulta 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 é a seguinte:
- element=2: saída do elemento na lista de permissões por html_sanitize_element
- attribute=1: saída de qualquer atributo por html_sanitize_attribute
- style_property=1: saída de qualquer propriedade de estilo por html_sanitize_style_property
- style_property_value=1: verifique o valor do estilo para a função url e a função expression para evitar injeções XSS por style_property_value
- url_protocol=1: verifique a lista de permissões de url_protocol para URL absolutas por html_sanitize_url_protocol
- url_domain=0: não verifique o domínio da URL para URL absolutas
- iframe_url_protocol=1: é o mesmo que url_protocol, mas apenas para
iframe.srcpor html_sanitize_iframe_url_protocol - iframe_url_domain=0: é o mesmo que url_domain, mas apenas para
iframe.srcpor html_sanitize_iframe_url_domain
Com ngx_http_html_sanitize_module, temos a capacidade de especificar se os elementos HTML5, atributos e propriedades CSS inline devem ser exibidos por directive e querystring como a seguir:
elemento na lista de permissões
- desabilitar elemento:
se não quisermos exibir nenhum elemento, podemos fazer o seguinte:
curl -X POST -d "<h1>h1</h1>" http://127.0.0.1:8888/sanitize?element=0
- habilitar elemento:
se quisermos exibir qualquer elemento, podemos fazer o seguinte:
$ 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>
- habilitar elemento na lista de permissões:
se quisermos exibir elementos na lista de permissões, podemos fazer o seguinte:
$ curl -X POST -d "<h1>h1</h1><h7>h7</h7>" http://127.0.0.1:8888/sanitize?element=1
<h1>h1</h1>
atributo na lista de permissões
- desabilitar atributo:
se não quisermos exibir nenhum atributo, podemos fazer o seguinte:
curl -X POST -d "<h1 ha=\"ha\">h1</h1>" "http://127.0.0.1:8888/sanitize?element=1&attribute=0"
<h1>h1</h1>
- habilitar atributo:
se quisermos exibir qualquer atributo, podemos fazer o seguinte:
$ 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>
- habilitar atributo na lista de permissões:
se quisermos exibir atributos na lista de permissões, podemos fazer o seguinte:
$ curl -X POST -d "<img src=\"/\" ha=\"ha\" />" "http://127.0.0.1:8888/sanitize?element=1&attribute=2"
<img src="/" />
propriedade de estilo na lista de permissões
- desabilitar propriedade de estilo:
se não quisermos exibir nenhuma propriedade de estilo, podemos fazer o seguinte:
# Não irá exibir nenhuma propriedade de estilo
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>
- habilitar propriedade de estilo:
se quisermos exibir qualquer propriedade de estilo, podemos fazer o seguinte:
$ 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>
- habilitar propriedade de estilo na lista de permissões:
se quisermos exibir propriedades de estilo na lista de permissões, podemos fazer o seguinte:
$ 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>
Descrição
Agora a implementação do ngx_http_html_sanitize_module é baseada no gumbo-parser e katana-parser. E fazemos a combinação sobre isso e executamos no nginx como um serviço web central mantido por profissionais de segurança para descartar diferenças de nível de linguagem. Se quisermos obter um desempenho mais alto (aqui está o brenchmark), é recomendado escrever uma biblioteca de nível de linguagem envolvendo uma biblioteca C pura para superar a sobrecarga da transmissão de rede.
Benchmark
Testando com wrk -s benchmarks/shot.lua -d 60s "http://127.0.0.1:8888" em Intel(R) Xeon(R) CPU E5-2630 v3 @ 2.40GHz e 64GB de memória
| Nome | Tamanho | Latência Média | 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 |
Diretiva
html_sanitize
syntax: html_sanitize on | off
default: html_sanitize on
context: location
Especifica se habilita o manipulador de sanitização HTML no contexto de localização
html_sanitize_hash_max_size
syntax: html_sanitize_hash_max_size size
default: html_sanitize_hash_max_size 2048
context: location
Define o tamanho máximo das tabelas hash de elemento, atributo, propriedade de estilo, url_protocol, url_domain, iframe_url_protocol, iframe_url_domain.
html_sanitize_hash_bucket_size
syntax: html_sanitize_hash_bucket_size size
default: html_sanitize_hash_bucket_size 32|64|128
context: location
Define o tamanho do bucket para elemento, atributo, propriedade de estilo, url_protocol, url_domain, iframe_url_protocol, iframe_url_domain. O valor padrão depende do tamanho da linha de cache do processador.
html_sanitize_element
syntax: html_sanitize_element element ...
default: -
context: location
Define os elementos HTML5 na lista de permissões ao habilitar o elemento na lista de permissões definindo o modo de lista de permissões da string de consulta element como o seguinte:
html_sanitize_element html head body;
html_sanitize_attribute
syntax: html_sanitize_attribute attribute ...
default: -
context: location
Define os atributos HTML5 na lista de permissões ao habilitar o elemento na lista de permissões definindo o modo de lista de permissões da string de consulta attribute como o seguinte:
html_sanitize_attribute a.href h1.class;
PS: o formato do atributo deve ser o mesmo que element.attribute e suporta *.attribute (asterisco prefixado) e element.* (asterisco sufixado)
html_sanitize_style_property
syntax: html_sanitize_style_property property ...
default: -
context: location
Define a propriedade CSS na lista de permissões ao habilitar o elemento na lista de permissões definindo o modo de lista de permissões da string de consulta style_property como o seguinte:
html_sanitize_style_property color background-color;
html_sanitize_url_protocol
syntax: html_sanitize_url_protocol [protocol] ...
default: -
context: location
Define o protocolo de URL permitido no linkable attribute quando apenas a URL é absoluta em vez de relativa e habilita a verificação do protocolo da URL definindo o modo de verificação da string de consulta url_protocol como o seguinte:
html_sanitize_url_protocol http https tel;
html_sanitize_url_domain
syntax: html_sanitize_url_domain domain ...
default: -
context: location
Define o domínio de URL permitido no linkable attribute quando apenas a URL é absoluta em vez de relativa e habilita a verificação do protocolo da URL, verificação do domínio da URL definindo o modo de verificação da string de consulta url_protocol e o modo de verificação da string de consulta url_domain[#url_domain] como o seguinte:
html_sanitize_url_domain *.google.com google.com;
html_sanitize_iframe_url_protocol
syntax: html_sanitize_iframe_url_protocol [protocol] ...
default: -
context: location
é o mesmo que html_sanitize_url_protocol, mas apenas para o atributo iframe.src
html_sanitize_iframe_url_protocol http https tel;
html_sanitize_iframe_url_domain
syntax: html_sanitize_iframe_url_domain [protocol] ...
default: -
context: location
é o mesmo que html_sanitize_url_domain, mas apenas para o atributo iframe.src
html_sanitize_iframe_url_domain *.facebook.com facebook.com;
linkable_attribute
Os atributos linkáveis são os seguintes:
- a.href
- blockquote.cite
- q.cite
- del.cite
- img.src
- ins.cite
- iframe.src
- função CSS URL
Querystring
a string de consulta da URL de solicitação é usada para controlar a ação interna do ngx_http_html_sanitize_module.
document
value: 0 ou 1
default: 0
context: querystring
Especifica se deve adicionar <!DOCTYPE> ao corpo da resposta
html
value: 0 ou 1
default: 0
context: querystring
Especifica se deve adicionar <html></html> ao corpo da resposta
script
value: 0 ou 1
default: 0
context: querystring
Especifica se deve permitir <script></script>
style
value: 0 ou 1
default: 0
context: querystring
Especifica se deve permitir <style></style>
context
value: [0, 150)
default: 38(GUMBO_TAG_DIV)
context: querystring
Especifica o contexto do gumbo-parser com o valor neste arquivo tag_enum.h
element
value: 0、1、2
default: 0
context: querystring
Especifica o modo de saída do elemento com o valor como o seguinte:
- 0: não exibir elemento
- 1: exibir todos os elementos
- 2: exibir elementos na lista de permissões
attribute
value: 0、1、2
default: 0
context: querystring
Especifica o modo de saída do atributo com o valor como o seguinte:
- 0: não exibir atributos
- 1: exibir todos os atributos
- 2: exibir atributos na lista de permissões
style_property
value: 0、1、2
default: 0
context: querystring
Especifica o modo de saída da propriedade CSS com o valor como o seguinte:
- 0: não exibir propriedade CSS
- 1: exibir todas as propriedades CSS
- 2: exibir propriedades CSS na lista de permissões
style_property_value
value: 0、1
default: 0
context: querystring
Especifica o modo de saída do valor da propriedade CSS com o valor como o seguinte:
- 0: não verificar o valor da propriedade CSS
- 1: verificar o valor da propriedade CSS para a função URL e a função de expressão do IE para evitar injeções XSS
url_protocol
value: 0、1
default: 0
context: querystring
Especifica se deve verificar o protocolo da URL no linkable_attribute. O valor é como o seguinte:
- 0: não verificar o protocolo da URL
- 1: exibir o protocolo da URL na lista de permissões
url_domain
value: 0、1
default: 0
context: querystring
Especifica se deve verificar o domínio da URL no linkable_attribute ao habilitar a verificação do url_protocol. O valor é como o seguinte:
- 0: não verificar o domínio da URL
- 1: exibir o domínio da URL na lista de permissões
iframe_url_protocol
value: 0、1
default: 0
context: querystring
é o mesmo que url_protocol, mas apenas para iframe.src
iframe_url_domain
value: 0、1
default: 0
context: querystring
é o mesmo que url_domain, mas apenas para iframe.src
GitHub
Você pode encontrar dicas adicionais de configuração e documentação para este módulo no repositório do GitHub para nginx-module-html-sanitize.