html-sanitize: module NGINX pour assainir HTML 5 avec des éléments, attributs et CSS sur liste blanche
Installation
Vous pouvez installer ce module dans n'importe quelle distribution basée sur RHEL, y compris, mais sans s'y limiter :
- RedHat Enterprise Linux 7, 8, 9 et 10
- CentOS 7, 8, 9
- AlmaLinux 8, 9
- Rocky Linux 8, 9
- Amazon Linux 2 et 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
Activez le module en ajoutant ce qui suit en haut de /etc/nginx/nginx.conf :
load_module modules/ngx_http_html_sanitize_module.so;
Ce document décrit nginx-module-html-sanitize v0.2.6 publié le 07 mars 2026.
Exemple
Voici un exemple de configuration nginx selon https://dev.w3.org/html5/html-author/#the-elements comme suit :
server {
listen 8888;
location = /sanitize {
# Définir explicitement l'encodage utf-8
add_header Content-Type "text/html; charset=UTF-8";
client_body_buffer_size 10M;
client_max_body_size 10M;
html_sanitize on;
# Vérifiez https://dev.w3.org/html5/html-author/#the-elements
# Élément racine
html_sanitize_element html;
# Métadonnées du document
html_sanitize_element head title base link meta style;
# Scripting
html_sanitize_element script noscript;
# Sections
html_sanitize_element body section nav article aside h1 h2 h3 h4 h5 h6 header footer address;
# Contenu groupé
html_sanitize_element p hr br pre dialog blockquote ol ul li dl dt dd;
# Sémantique de niveau texte
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;
# Édits
html_sanitize_element ins del;
# Contenu intégré
htlm_sanitize_element figure img iframe embed object param video audio source canvas map area;
# Données tabulaires
html_sanitize_element table caption colgroup col tbody thead tfoot tr td th;
# Formulaires
html_sanitize_element form fieldset label input button select datalist optgroup option textare output;
# Éléments interactifs
html_sanitize_element details command bb menu;
# Éléments divers
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;
}
}
Et il est recommandé d'utiliser la commande ci-dessous pour assainir 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>
Cette chaîne de requête 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 est comme suit :
- element=2 : sortie des éléments sur liste blanche par html_sanitize_element
- attribute=1 : sortie de tout attribut par html_sanitize_attribute
- style_property=1 : sortie de toute propriété de style par html_sanitize_style_property
- style_property_value=1 : vérifiez la valeur de style pour la fonction url et la fonction expression pour éviter l'injection XSS par style_property_value
- url_protocol=1 : vérifiez le protocole d'URL sur liste blanche pour les URL absolues par html_sanitize_url_protocol
- url_domain=0 : ne pas vérifier le domaine de l'URL pour les URL absolues
- iframe_url_protocol=1 : est le même que url_protocol mais uniquement pour
iframe.srcpar html_sanitize_iframe_url_protocol - iframe_url_domain=0 : est le même que url_domain mais uniquement pour
iframe.srcpar html_sanitize_iframe_url_domain
Avec ngx_http_html_sanitize_module, nous avons la capacité de spécifier si les éléments HTML5, attributs et propriétés CSS en ligne sont sortis par directive et querystring comme suit :
élément sur liste blanche
- désactiver l'élément :
si nous ne voulons pas sortir d'élément, nous pouvons faire comme suit :
curl -X POST -d "<h1>h1</h1>" http://127.0.0.1:8888/sanitize?element=0
- activer l'élément :
si nous voulons sortir n'importe quel élément, nous pouvons faire comme suit :
$ 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>
- activer l'élément sur liste blanche :
si nous voulons sortir des éléments sur liste blanche, nous pouvons faire comme suit :
$ curl -X POST -d "<h1>h1</h1><h7>h7</h7>" http://127.0.0.1:8888/sanitize?element=1
<h1>h1</h1>
attribut sur liste blanche
- désactiver l'attribut :
si nous ne voulons pas sortir d'attribut, nous pouvons faire comme suit :
curl -X POST -d "<h1 ha=\"ha\">h1</h1>" "http://127.0.0.1:8888/sanitize?element=1&attribute=0"
<h1>h1</h1>
- activer l'attribut :
si nous voulons sortir n'importe quel attribut, nous pouvons faire comme suit :
$ 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>
- activer l'attribut sur liste blanche :
si nous voulons sortir des éléments sur liste blanche, nous pouvons faire comme suit :
$ curl -X POST -d "<img src=\"/\" ha=\"ha\" />" "http://127.0.0.1:8888/sanitize?element=1&attribute=2"
<img src="/" />
propriété de style sur liste blanche
- désactiver la propriété de style :
si nous ne voulons pas sortir de propriété de style, nous pouvons faire comme suit :
# Cela ne sortira aucune propriété de style
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>
- activer la propriété de style :
si nous voulons sortir n'importe quelle propriété de style, nous pouvons faire comme suit :
$ 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>
- activer la propriété de style sur liste blanche :
si nous voulons sortir des propriétés de style sur liste blanche, nous pouvons faire comme suit :
$ 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>
Description
L'implémentation actuelle de ngx_http_html_sanitize_module est basée sur gumbo-parser et katana-parser. Et nous avons fait le combo dessus puis l'avons exécuté sur nginx en tant que service web central maintenu par des professionnels de la sécurité pour éliminer les différences de niveau de langage. Si nous voulons obtenir des performances encore plus élevées (ici est le brenchmark), il est recommandé d'écrire une bibliothèque de niveau langage enveloppant au-dessus de la bibliothèque C pure pour surmonter les frais généraux de transmission réseau.
Benchmark
Test avec wrk -s benchmarks/shot.lua -d 60s "http://127.0.0.1:8888" sur Intel(R) Xeon(R) CPU E5-2630 v3 @ 2.40GHz et 64 Go de mémoire
| Nom | Taille | Latence Moyenne | QPS |
|---|---|---|---|
| hacker_news.html | 30Ko | 9.06ms | 2921.82 |
| baidu.html | 76Ko | 13.41ms | 1815.75 |
| arabic_newspapers.html | 78Ko | 16.58ms | 1112.70 |
| bbc.html | 115Ko | 17.96ms | 993.12 |
| xinhua.html | 323Ko | 33.37ms | 275.39 |
| google.html | 336Ko | 26.78ms | 351.54 |
| yahoo.html | 430Ko | 29.16ms | 323.04 |
| wikipedia.html | 511Ko | 57.62ms | 160.10 |
| html5_spec.html | 7.7Mo | 1.63s | 2.00 |
Directive
html_sanitize
syntaxe : html_sanitize on | off
par défaut : html_sanitize on
contexte : location
Spécifie si le gestionnaire d'assainissement HTML est activé dans le contexte de localisation
html_sanitize_hash_max_size
syntaxe : html_sanitize_hash_max_size size
par défaut : html_sanitize_hash_max_size 2048
contexte : location
Définit la taille maximale des tables de hachage pour les éléments, attributs, propriétés de style, protocoles d'URL, domaines d'URL, protocoles d'URL iframe, domaines d'URL iframe.
html_sanitize_hash_bucket_size
syntaxe : html_sanitize_hash_bucket_size size
par défaut : html_sanitize_hash_bucket_size 32|64|128
contexte : location
Définit la taille du seau pour les éléments, attributs, propriétés de style, protocoles d'URL, domaines d'URL, protocoles d'URL iframe, domaines d'URL iframe. La valeur par défaut dépend de la taille de la ligne de cache du processeur.
html_sanitize_element
syntaxe : html_sanitize_element element ...
par défaut : -
contexte : location
Définit les éléments HTML5 sur liste blanche lorsque l'élément sur liste blanche est activé en définissant le mode liste blanche de la chaîne de requête element comme suit :
html_sanitize_element html head body;
html_sanitize_attribute
syntaxe : html_sanitize_attribute attribute ...
par défaut : -
contexte : location
Définit les attributs HTML5 sur liste blanche lorsque l'élément sur liste blanche est activé en définissant le mode liste blanche de la chaîne de requête attribute comme suit :
html_sanitize_attribute a.href h1.class;
PS : le format de l'attribut doit être le même que element.attribute et prend en charge *.attribute (astérisque en préfixe) et element.* (astérisque en suffixe)
html_sanitize_style_property
syntaxe : html_sanitize_style_property property ...
par défaut : -
contexte : location
Définit la propriété CSS sur liste blanche lorsque l'élément sur liste blanche est activé en définissant le mode liste blanche de la chaîne de requête style_property comme suit :
html_sanitize_style_property color background-color;
html_sanitize_url_protocol
syntaxe : html_sanitize_url_protocol [protocol] ...
par défaut : -
contexte : location
Définit le protocole d'URL autorisé dans linkable attribute lorsque seule l'URL est absolue plutôt que relative et active la vérification du protocole d'URL en définissant le mode de vérification url_protocol de la chaîne de requête comme suit :
html_sanitize_url_protocol http https tel;
html_sanitize_url_domain
syntaxe : html_sanitize_url_domain domain ...
par défaut : -
contexte : location
Définit le domaine d'URL autorisé dans linkable attribute lorsque seule l'URL est absolue plutôt que relative et active la vérification du protocole d'URL, la vérification du domaine d'URL en définissant le mode de vérification url_protocol de la chaîne de requête et le mode de vérification url_domain[#url_domain] de la chaîne de requête comme suit :
html_sanitize_url_domain *.google.com google.com;
html_sanitize_iframe_url_protocol
syntaxe : html_sanitize_iframe_url_protocol [protocol] ...
par défaut : -
contexte : location
est le même que html_sanitize_url_protocol mais uniquement pour l'attribut iframe.src
html_sanitize_iframe_url_protocol http https tel;
html_sanitize_iframe_url_domain
syntaxe : html_sanitize_iframe_url_domain [protocol] ...
par défaut : -
contexte : location
est le même que html_sanitize_url_domain mais uniquement pour l'attribut iframe.src
html_sanitize_iframe_url_domain *.facebook.com facebook.com;
linkable_attribute
L'attribut cliquable est le suivant :
- a.href
- blockquote.cite
- q.cite
- del.cite
- img.src
- ins.cite
- iframe.src
- fonction URL CSS
Querystring
la chaîne de requête de l'URL de la requête est utilisée pour contrôler l'action interne de ngx_http_html_sanitize_module.
document
valeur : 0 ou 1
par défaut : 0
contexte : chaîne de requête
Spécifie s'il faut ajouter <!DOCTYPE> au corps de la réponse
html
valeur : 0 ou 1
par défaut : 0
contexte : chaîne de requête
Spécifie s'il faut ajouter <html></html> au corps de la réponse
script
valeur : 0 ou 1
par défaut : 0
contexte : chaîne de requête
Spécifie s'il faut autoriser <script></script>
style
valeur : 0 ou 1
par défaut : 0
contexte : chaîne de requête
Spécifie s'il faut autoriser <style></style>
context
valeur : [0, 150)
par défaut : 38(GUMBO_TAG_DIV)
contexte : chaîne de requête
Spécifie le contexte du gumbo-parser avec la valeur dans ce fichier tag_enum.h
element
valeur : 0、1、2
par défaut : 0
contexte : chaîne de requête
Spécifie le mode de sortie de l'élément avec la valeur comme suit :
- 0 : ne pas sortir d'élément
- 1 : sortir tous les éléments
- 2 : sortir les éléments sur liste blanche
attribute
valeur : 0、1、2
par défaut : 0
contexte : chaîne de requête
Spécifie le mode de sortie de l'attribut avec la valeur comme suit :
- 0 : ne pas sortir d'attributs
- 1 : sortir tous les attributs
- 2 : sortir les attributs sur liste blanche
style_property
valeur : 0、1、2
par défaut : 0
contexte : chaîne de requête
Spécifie le mode de sortie de la propriété CSS avec la valeur comme suit :
- 0 : ne pas sortir de propriété CSS
- 1 : sortir toutes les propriétés CSS
- 2 : sortir les propriétés CSS sur liste blanche
style_property_value
valeur : 0、1
par défaut : 0
contexte : chaîne de requête
Spécifie le mode de sortie de la valeur de la propriété CSS avec la valeur comme suit :
- 0 : ne pas vérifier la valeur de la propriété CSS
- 1 : vérifier la valeur de la propriété CSS pour la fonction URL et la fonction d'expression IE pour éviter l'injection XSS
url_protocol
valeur : 0、1
par défaut : 0
contexte : chaîne de requête
Spécifie s'il faut vérifier le protocole d'URL dans linkable_attribute. La valeur est comme suit :
- 0 : ne pas vérifier le protocole d'URL
- 1 : sortir le protocole d'URL sur liste blanche
url_domain
valeur : 0、1
par défaut : 0
contexte : chaîne de requête
Spécifie s'il faut vérifier le domaine d'URL dans linkable_attribute lorsque la vérification url_protocol est activée. La valeur est comme suit :
- 0 : ne pas vérifier le domaine d'URL
- 1 : sortir le domaine d'URL sur liste blanche
iframe_url_protocol
valeur : 0、1
par défaut : 0
contexte : chaîne de requête
est le même que url_protocol mais uniquement pour iframe.src
iframe_url_domain
valeur : 0、1
par défaut : 0
contexte : chaîne de requête
est le même que url_domain mais uniquement pour iframe.src
GitHub
Vous pouvez trouver des conseils de configuration supplémentaires et de la documentation pour ce module dans le dépôt GitHub pour nginx-module-html-sanitize.