Aller au contenu

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 :

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.