Encodeur / décodeur d'entités HTML, gratuit
Convertissez les caractères spéciaux en entités HTML et inversement.
Entités HTML courantes
| Caractère | Entité | Numérique | Description |
|---|---|---|---|
| & | & | & | Esperluette |
| < | < | < | Inférieur à |
| > | > | > | Supérieur à |
| " | " | " | Guillemet double |
| ' | ' | ' | Apostrophe |
| |   | Espace insécable | |
| © | © | © | Copyright |
| ® | ® | ® | Marque déposée |
| ™ | ™ | ™ | Marque de commerce |
| € | € | € | Signe euro |
Pourquoi utiliser les entités HTML ?
Les caractères comme <, > et & ont une signification spéciale en HTML. Si vous les incluez littéralement dans votre HTML, le navigateur les interprète comme du code, non comme du contenu. Encoder ces caractères en entités évite les problèmes de rendu et les vulnérabilités de script intersite (XSS).
Questions fréquentes
Quelle est la différence entre entités nommées et numériques ?
Les entités nommées utilisent des noms descriptifs (&, ©) tandis que les entités numériques utilisent des points de code Unicode (&, ©). Les deux s'affichent à l'identique. Les entités nommées sont plus lisibles ; les entités numériques fonctionnent pour tout caractère Unicode.
Dois-je encoder tous les caractères spéciaux ?
Au minimum, vous devez encoder &, <, > et " dans le contenu HTML et les valeurs d'attributs. Les navigateurs modernes gèrent la plupart des autres caractères nativement si votre document utilise l'encodage UTF-8.
Trois formes, un seul caractère
Une « entité » HTML, formellement une référence de caractère, est une séquence d'échappement qui représente un caractère à l'aide d'une suite de caractères ASCII ordinaires. Le HTML Living Standard définit trois formes syntaxiques concrètes :
- Nommée :
&suivie d'un nom issu de la table des références de caractères nommés du WHATWG, terminée par un point-virgule. Exemple :©pour ©. - Numérique décimale :
&#suivi du point de code Unicode en base 10, terminé par un point-virgule. Exemple :©. - Numérique hexadécimale :
&#xsuivi du point de code en base 16, terminé par un point-virgule. Exemple :©.
Les trois formes sont interchangeables une fois rendues : ©, © et © produisent toutes le caractère visible © car elles correspondent toutes au point de code Unicode U+00A9. Le choix entre elles est une question de lisibilité du code source, pas de comportement du navigateur. L'hexadécimal tend à correspondre aux tables Unicode publiées (qui utilisent la notation U+XXXX), si bien que ♥ est plus proche de la notation officielle U+2665 que ♥. Les références numériques fonctionnent pour n'importe quel caractère Unicode, y compris les émojis du plan astral, 😀 s'affiche comme 😀 (U+1F600 GRINNING FACE).
Pourquoi les entités existent
Trois raisons distinctes, historiques et pratiques :
- Échapper les caractères qui ont une signification syntaxique en HTML. L'analyseur utilise certains caractères ASCII comme symboles de contrôle.
<ouvre une balise,>en ferme une,&introduit une référence, et les caractères de guillemet délimitent les valeurs d'attribut. Si vous voulez que l'un d'eux apparaisse comme texte littéral, vous devez l'échapper. - Représenter des caractères absents de l'encodage du document. Avant que l'UTF-8 ne devienne universel sur le web (il n'a franchi la barre des 50 % que vers 2010), la plupart du HTML était servi en US-ASCII, ISO-8859-1 ou Windows-1252. Dans ces encodages à un octet, des caractères comme ©, €, ≈ ou α ne pouvaient tout simplement pas être exprimés par un octet littéral. Écrire
©,€ou≈était le seul moyen d'atteindre ces points de code. - Signaler l'intention de l'auteur pour les caractères invisibles ou ambigus. Même sur une page UTF-8, une espace insécable littérale (U+00A0) est visuellement identique à une espace normale, écrire
rend l'intention évidente pour quiconque lit la source.
Le W3C recommande désormais d'utiliser des caractères Unicode littéraux lorsque c'est possible plutôt que des entités, « pour l'accessibilité et la lisibilité ». Les entités restent utiles pour les cinq échappements obligatoires, ainsi que pour les caractères réellement invisibles ou ambigus.
Les cinq incontournables
Les cinq caractères que vous devez absolument échapper lorsque vous insérez du contenu non fiable dans du HTML sont <, >, &, " et '. L'aide-mémoire OWASP de prévention du cross-site scripting les énumère comme l'ensemble d'échappement minimal requis :
| Caractère | Nommée | Décimale | Hexadécimale |
|---|---|---|---|
| < | < | < | < |
| > | > | > | > |
| & | & | & | & |
| " | " | " | " |
| ' | ' / ' | ' | ' |
La règle générale : chaque fois que vous placez du texte non fiable dans une sortie HTML, échappez d'abord ces cinq caractères. Ne pas le faire est la cause première de l'écrasante majorité des vulnérabilités XSS stockées et réfléchies.
Le piège de l'apostrophe
' ne fait pas partie de HTML 4, elle a été définie à l'origine uniquement par XML 1.0 puis héritée dans XHTML 1.0. Internet Explorer antérieur à la version 9 (sortie en 2011) refusait de l'afficher comme ' et montrait le texte littéral '. L'entité a été ajoutée spécifiquement à HTML5 et est désormais sûre dans tous les navigateurs modernes, mais pour une compatibilité maximale entre navigateurs et entre spécifications, OWASP et la plupart des bibliothèques d'assainissement d'entreprise recommandent encore d'émettre ' plutôt que ' pour échapper les apostrophes, en particulier dans le code critique pour la sécurité.
Quand encoder et quand ne pas le faire
La décision d'encoder dépend de l'endroit où le texte va se retrouver dans la sortie, et non de ce qu'il contient. C'est le point le plus mal compris de la sécurité HTML. Les recommandations de l'OWASP distinguent les contextes :
- Contenu d'élément HTML : échappez
< > & "(et'par excès de prudence). - Valeurs d'attribut HTML : échappez les mêmes plus le caractère de guillemet ; utilisez toujours des attributs entre guillemets.
- Contexte JavaScript : utilisez l'échappement JavaScript, pas l'échappement HTML :
\xHHou\uHHHH. - Contexte CSS : utilisez l'échappement CSS :
\HHsuivi d'une espace. - Contexte de paramètre URL / URI : utilisez l'encodage pourcent (
%HH), pas l'encodage HTML.
Chaque contexte a ses propres règles d'échappement. Les mélanger est en soi une vulnérabilité, par exemple, encoder en pourcent un < vers %3C ne protège pas contre le XSS dans un contexte de contenu HTML, où %3C n'est que le texte littéral %3C.
Évitez le double encodage. Un bug courant consiste à échapper les données à leur lecture dans le système, de nouveau à leur stockage, encore à leur relecture, et encore à leur rendu. Résultat : l'utilisateur a tapé 5 < 10, la base de données stocke 5 &lt; 10, la page affiche 5 < 10 au lieu de l'original. La discipline, c'est : stocker l'Unicode brut, encoder une seule fois, au moment de la sortie, pour le contexte précis.
Encodage HTML ou encodage URL
Deux systèmes d'échappement différents pour deux contextes différents, sans cesse confondus :
| Entité HTML | URL / pourcent | |
|---|---|---|
| Norme | HTML Living Standard | RFC 3986 |
| Format | &name; ou &#NN; | %HH (octet hexa) |
| Contexte | Balisage HTML, corps d'éléments et attributs | URL, chaînes de requête, corps de requête encodés en formulaire |
| Espace | (insécable), jamais d'espace simple | %20 ou + |
| Fonction JS | - (géré par l'analyseur) | encodeURIComponent() / encodeURI() |
Une URL placée dans une valeur d'attribut HTML reçoit les deux échappements superposés : d'abord l'encodage pourcent pour les caractères illégaux dans une URL, puis l'encodage HTML pour tout & < > " présent dans l'URL obtenue. C'est pourquoi les esperluettes de chaîne de requête à l'intérieur d'un attribut href deviennent & dans la sérialisation HTML.
Brève histoire
HTML 2.0 (RFC 1866, 1995) a hérité du mécanisme d'entités de SGML avec environ 50 entités nommées pour ISO Latin 1. HTML 3.2 (W3C, janvier 1997) a ajouté les entités mathématiques et de symboles. HTML 4.01 (W3C, décembre 1999) a finalisé trois jeux d'entités (Latin-1, Special et Symbol) totalisant 252 entités nommées, ce qui est à l'origine du chiffre « 252 » que l'on voit encore dans les anciens tutoriels. HTML5 / WHATWG (Living Standard, en cours) a absorbé et considérablement étendu la table à plus de 2 000 entrées, principalement pour couvrir MathML et un ensemble Unicode plus large. XML 1.0 (1998) définit son propre jeu minimal réduit aux cinq incontournables (< > & " '), ce jeu minimal est à l'origine de '.
Autres questions
Dans du code moderne, que dois-je réellement utiliser ?
Le code de production ne code généralement pas les entités à la main, il fait appel à une bibliothèque. DOMPurify pour l'assainissement HTML côté client. html.escape() dans la bibliothèque standard de Python. htmlspecialchars() en PHP. html/template en Go (échappement automatique activé par défaut). OWASP Java Encoder pour Java. En React, écrire <div>{userInput}</div> échappe automatiquement ; l'échappatoire dangerouslySetInnerHTML est nommée ainsi pour décourager un usage à la légère. Un encodeur autonome comme celui-ci est utile comme outil de vérification / débogage, pas comme remplacement de ces bibliothèques.
Qu'en est-il des balises dans les modèles d'e-mail ?
Les clients de messagerie plus anciens (Outlook en particulier) interprètent un & non encodé comme un attribut mal formé et peuvent supprimer le balisage environnant. Les développeurs d'e-mails HTML apprennent à encoder en entités chaque caractère spécial par précaution. Il en va de même pour les systèmes de forum de type BBCode qui réécrivent le contenu avant de le stocker ; les allers-retours peuvent introduire des entités littérales inattendues.
Quelle est la différence entre textContent et innerHTML en JavaScript ?
La règle de prévention XSS la plus importante en JavaScript pur : utilisez element.textContent = userInput plutôt que element.innerHTML = userInput. Définir textContent écrit la chaîne comme texte littéral, le navigateur gère tout l'échappement en interne. Définir innerHTML analyse la chaîne comme du HTML, exécutant toutes les balises <script> ou les attributs gestionnaires d'événements qu'elle contient. Si du balisage est réellement nécessaire, utilisez une bibliothèque comme DOMPurify pour assainir au préalable.
L'encodeur gère-t-il les émojis ?
Oui, via les références numériques. Il n'existe pas d'entités nommées pour les émojis, ils utilisent tous la forme numérique. 😀 s'affiche comme 😀, ❤️ comme le cœur rouge ❤️ (point de code du cœur plus sélecteur de présentation émoji). Le navigateur gère en interne la conversion implicite en paire de substitution UTF-16 ; vous ne devez pas écrire les moitiés de substitution manuellement.
Quelque chose est-il envoyé à un serveur ?
Non. L'encodage et le décodage sont des transformations de chaînes par fonctions pures qui s'exécutent entièrement dans votre navigateur via JavaScript. Rien de votre saisie n'est téléversé ; la page fonctionne hors ligne une fois chargée. C'est important, car les encodeurs en ligne qui font un aller-retour avec votre charge utile de test peuvent eux-mêmes devenir un vecteur XSS si le site de test est compromis.