5 points par GN⁺ 2026-02-26 | 2 commentaires | Partager sur WhatsApp
  • Pour prévenir les attaques XSS, l’une des principales vulnérabilités du web, Firefox est le premier à prendre en charge l’API Sanitizer standardisée
  • En utilisant la méthode setHTML() à la place de innerHTML, le HTML non fiable est automatiquement assaini (sanitize) avant son insertion dans le DOM, ce qui supprime les scripts malveillants
  • Les développeurs peuvent contrôler les éléments et attributs autorisés via une configuration personnalisée si les réglages par défaut sont trop stricts ou pas assez
  • Associée aux Trusted Types, cette fonctionnalité de Firefox élève le niveau de sécurité du web dans son ensemble et permet de prévenir les XSS même sans équipe sécurité dédiée

Vulnérabilités XSS et réponse de Firefox

  • Le cross-site scripting (XSS) se produit lorsqu’un attaquant injecte du HTML ou du JavaScript arbitraire via un contenu saisi par l’utilisateur
    • Il peut alors surveiller les interactions des utilisateurs ou voler des données
    • Les XSS sont classées parmi les trois principales vulnérabilités du web (CWE-79) depuis près de dix ans
  • Firefox renforce la défense contre les XSS depuis 2009 en jouant un rôle moteur dans le standard Content-Security-Policy (CSP)
    • Le CSP limite les ressources qu’un site web peut charger et exécuter
    • Mais son adoption à grande échelle restait limitée, car il exigeait des changements dans la structure des sites existants et des revues de sécurité continues

Rôle de l’API Sanitizer et de setHTML()

  • L’API Sanitizer fournit une méthode standardisée pour transformer du HTML malveillant en contenu inoffensif
    • Dans l’exemple de code, l’élément <img src="x" onclick="alert('XSS')"> est supprimé et seul <h1>Hello my name is</h1> reste
  • La méthode setHTML() applique automatiquement le processus d’assainissement lors de l’insertion de HTML, garantissant un comportement sûr par défaut
    • Il suffit de remplacer une affectation innerHTML existante par setHTML() pour obtenir une protection XSS robuste
  • Si la configuration par défaut est trop stricte ou trop permissive, les développeurs peuvent définir les éléments et attributs HTML autorisés via une configuration personnalisée
    • L’outil Sanitizer API playground peut être utilisé pour faire des essais

Association avec les Trusted Types

  • L’API Trusted Types offre une couche de sécurité supplémentaire en centralisant le contrôle du parsing et de l’insertion du HTML
    • Lors de l’utilisation de setHTML(), il est facile d’appliquer une politique Trusted Types
    • Une politique stricte peut n’autoriser que setHTML() et bloquer les autres méthodes d’insertion risquées, contribuant ainsi à prévenir de futures régressions XSS

Effets des améliorations de sécurité dans Firefox 148

  • Firefox 148 prend en charge à la fois l’API Sanitizer et les Trusted Types, ce qui améliore fortement le niveau de sécurité par défaut
  • Les développeurs peuvent prévenir les XSS avec de simples changements de code, sans politiques de sécurité complexes ni équipe sécurité dédiée
  • L’introduction de ce standard devrait contribuer à étendre un environnement web plus sûr à l’ensemble des navigateurs

Résumé

  • Firefox 148 aide les développeurs web à bloquer facilement les attaques XSS grâce à la méthode setHTML() et à l’API Sanitizer
  • Cette fonctionnalité comble les limites du CSP et marque une étape vers un standard web d’insertion HTML sûre par défaut
  • Associée aux Trusted Types, elle permet un maintien durable de la sécurité et la prévention des régressions XSS
  • En conséquence, Firefox conduit la transition vers un environnement web où la sécurité est le choix par défaut

2 commentaires

 
huiya 2026-02-26

Oh oui, c’est clairement le genre de chose dont on a besoin. Ce serait vraiment génial si tous les navigateurs le prenaient en charge.

 
GN⁺ 2026-02-26
Réactions sur Hacker News
  • Ce genre de fonctionnalité met toujours un peu mal à l’aise
    car il existe un mélange de méthodes qui traitent en toute sécurité une entrée utilisateur arbitraire et d’autres qui ne le font pas, et rien qu’au nom il est difficile de les distinguer
    Idéalement, les fonctions dangereuses devraient l’indiquer clairement dès leur nom
    En plus, la notion même de « sanitization » du HTML est floue, et il est difficile de juger si c’est réellement sûr

    • Il est vrai que la définition de « sûr » est floue, mais ici l’objectif est d’être safe vis-à-vis des XSS
      Les éléments et attributs capables d’exécuter des scripts sont supprimés, et cette logique fonctionne à l’intérieur du moteur du navigateur, ce qui permet un traitement plus précis qu’un sanitizer basé sur des chaînes de caractères
      Voir la documentation MDN de setHTML pour plus de détails
    • En réalité, la distinction est déjà claire
      elementNode.textContent est sûr même avec des entrées non fiables, alors que elementNode.innerHTML ne l’est pas
      Le premier échappe tous les caractères, le second n’échappe rien du tout
      Certains estiment que la « sanitization HTML » est un problème fondamentalement insoluble
      Voir ce commentaire pour la discussion associée
      Une API de ce type n’aurait pas dû passer l’étape de proposition
    • Au lieu de mélanger innerHTML et setHTML, il aurait fallu supprimer complètement innerHTML et utiliser setHTMLUnsafe lorsqu’on a besoin de l’ancien comportement
    • Ce serait bien si les développeurs web pouvaient désactiver via un réglage global des API obsolètes comme innerHTML
      Cela dit, dans ce cas le site pourrait ne plus fonctionner sur les anciens navigateurs
    • Si la page est servie avec l’en-tête Content-Security-Policy: require-trusted-types-for 'script', on peut bloquer le passage de chaînes ordinaires à des méthodes sans sanitizer
  • Si, comme dans l’exemple, on peut insérer des balises comme <h1> ou <br> dans un nom d’utilisateur, alors même si l’exécution de scripts est bloquée, on peut toujours faire de l’injection de balisage arbitraire
    On peut même modifier le CSS avec une balise <style>, et par exemple altérer le design d’une page de profil PayPal
    On peut se demander qui voudrait de ça

    • Cela peut tout de même être utile quand on veut permettre aux utilisateurs d’écrire en Markdown, comme sur un forum
      On peut ajouter une couche de défense en prenant le HTML généré par Markdown puis en le restreignant à nouveau avec un sanitizer qui n’autorise que certaines balises
    • Dans ce cas, il aurait fallu utiliser innerHTML non, mais innerText ou textContent
      setHTML est pensé comme un remplaçant de innerHTML
    • Si la configuration par défaut de setHTML() est trop stricte ou trop permissive, le développeur peut fournir une configuration personnalisée définissant explicitement les éléments HTML et attributs autorisés
    • Le CSS seul peut aussi créer des risques de sécurité, donc il faut rester prudent
      Voir ce fil pour la discussion associée
    • Par exemple
      .setHTML("<h1>Hello</h1>", new Sanitizer({}))
      
      dans ce cas tous les éléments sont supprimés
      Au final, côté backend il faut toujours sanitizer les noms d’utilisateur de manière standard, et à l’affichage il faut appliquer un échappement HTML
      Selon la RFC 2119, c’est une exigence de niveau « SHOULD »
  • Je suis content de voir arriver cette fonctionnalité, mais il faudra sans doute du temps avant que le support navigateur soit suffisamment répandu
    On peut vérifier l’état de la prise en charge sur Can I use

    • Comme pour d’autres API de navigateur, cela pourrait prendre quelques années, ou seulement quelques mois si l’on ne cible que les versions récentes
      En attendant, on peut utiliser un polyfill
  • Le titre était un peu sensationnaliste
    En pratique, on peut aussi implémenter une sanitization avec une fonction qui valide l’entrée avant de la passer à innerHTML
    Cela dit, ce genre de tentative donne finalement l’impression de réinventer la roue
    Et sur les anciennes versions de Firefox, hacks.mozilla.org ne s’ouvre même pas, tandis que sur Pale Moon ou SeaMonkey, MDN s’affiche mal
    On a l’impression qu’un « cartel des navigateurs » essaie de détruire le web

    • Dire que « ça peut se régler avec une fonction de validation d’entrée », c’est comme dire que « le C est sûr pour la mémoire s’il n’y a pas de bugs »
      C’est aussi un argument qui ne tient pas compte des problèmes de parser differential
  • La Sanitizer API peut devenir un footgun si elle est mal utilisée
    Il faut surtout faire attention lorsqu’on utilise le mode « remove »
    Personnellement, je pense qu’il vaudrait mieux s’en tenir à setText et ne permettre aucun ajout de HTML par l’utilisateur

    • Avec un Sanitizer fondé sur une allowlist, le risque diminue, mais tant qu’on utilise setHTML, il n’y aura pas de XSS
    • Mais que faire quand l’auteur de la page doit insérer de gros fragments HTML
      Vu la fréquence d’usage de innerHTML, il est difficile de l’exclure totalement
    • Au contraire, ce type d’API pourrait être encore plus dangereux en donnant l’illusion qu’il est « 100 % sûr »
  • Il est impressionnant de voir que tous les aspects de l’accès réseau sont désormais correctement contrôlés, et que la chaîne de sécurité est passée de la confiance dans le code à la confiance dans la configuration de l’hôte
    Les valeurs par défaut sont aussi sécurisées

  • Ce que je veux vraiment, c’est un élément <sandbox> capable d’exécuter du code dangereux en toute sécurité
    L’idée n’est pas de modifier le code dangereux, mais de pouvoir l’exécuter dans un environnement isolé
    Les iframe ont la contrainte de ne pas pouvoir s’intégrer naturellement au flux du DOM, et à une époque d’IA et de contenu dynamique croissant, il faut une encapsulation composable

  • J’aime vraiment le nom setHTMLUnsafe
    Les fonctions de sécurité échouent quand elles reposent sur un opt-in du développeur
    Il est plus efficace de faire en sorte que « le chemin dangereux paraisse dangereux »

  • Le nom set_html() est bien plus intuitif que inner_html
    Les API JavaScript sont vraiment incohérentes et mériteraient un jour d’être remises en ordre
    Ici la discussion porte sur la sécurité, mais lorsqu’on publie une nouvelle API, sa conception devrait aussi être propre

    • À strictement parler, c’est une API DOM
      Les API DOM donnent depuis longtemps, et encore aujourd’hui, l’impression d’avoir été conçues par des gens qui n’ont jamais créé d’API
  • Les développeurs des années 90 :

    SQL("select * from user where name = " + name);
    

    Les développeurs des années 2020 :

    div.innerHTML = "Hello " + user.name;
    
    • Les développeurs des années 2030 :
      "Summarize this email: " + email.contents
      
      La prompt injection n’est que le même problème sur une nouvelle technologie
      Nous n’avons rien appris des années 90