Encoder en entités HTML

Collez un texte et récupérez-le avec les caractères qui changent la façon dont un document s’analyse remplacés par leurs entités. Cela fait cinq caractères dans le cas ordinaire, et la version élargie — tout ce qui dépasse l’ASCII également — est proposée à part, parce que c’est un autre travail avec un autre coût. L’échappement a lieu dans cette page.

La première est ce que fait un moteur de gabarits. La seconde sert quand la chaîne traverse un système qui n’est pas propre en UTF-8.

Résultat

La réponse apparaît ici pendant que vous écrivez.

  • Où cela s’exécute

    Rien n’est envoyé, puisqu’il n’y a pas de fichier : tout est calculé dans cette page.

  • Sans file d’attente et sans compte

    Il répond aussi vite que votre machine le permet, et ne demande jamais qui vous êtes.

  • Autant de fois que vous voulez

    Rien n’est compté ni plafonné : répondre à nouveau ne nous coûte rien.

Comment cela fonctionne

  1. Collez le texte ou le balisage dans le champ.
  2. Choisissez l’étendue. Le réglage par défaut est les cinq caractères qui influent sur l’analyse.
  3. Copiez le résultat dans votre gabarit, votre champ de CMS ou votre documentation.

Cinq caractères décident si un texte reste un texte

Une esperluette ouvre une référence, un chevron ouvrant ouvre une balise, un chevron fermant la termine, et les deux sortes de guillemets terminent une valeur d’attribut. Tout le reste d’un document est inerte. Échappez ces cinq-là et un texte arbitraire peut être placé n’importe où dans une page en restant le texte que quelqu’un a écrit.

Laissez-les et le texte devient de la structure. C’est le mécanisme derrière les failles de type cross-site scripting, mais c’est aussi celui derrière une description produit qui avale la moitié d’un paragraphe parce qu’un rédacteur y a tapé « moins de 5 < 10 unités ». Le second cas arrive bien plus souvent et se remarque bien plus tard.

L’ordre des remplacements est là où cela dérape

L’esperluette doit être remplacée en premier. Traitez le chevron ouvrant d’abord et il devient `&lt;` — qui contient désormais une esperluette, que la passe suivante échappe, et la sortie devient `&amp;lt;`, affichée dans la page comme le texte littéral `&lt;`.

C’est une fonction de deux lignes, fausse exactement de cette manière dans une bonne part des implémentations que vous trouverez recopiées dans une réponse quelque part, et elle est fausse de façon invisible : un texte qui ne contient aucun des cinq ressort identique, donc un test écrit sur de la prose ordinaire passe. C’est pourquoi le test de celle-ci est écrit sur une chaîne contenant les deux caractères à la fois.

À quoi sert réellement d’échapper tout le reste

Pas à la sécurité. Les cinq caractères constituent la totalité de l’argument de sécurité ; échapper un `é` ne protège rien, et cela rend la sortie plus longue et illisible, ce qui est un coût réel pour la personne qui maintiendra le fichier où elle atterrira.

Cela sert à survivre à un système qui n’est pas propre en UTF-8 : un jeu de caractères mal déclaré quelque part, une colonne de base restée en latin1, un export vers un logiciel antérieur à la décision que le web est en UTF-8. Dans tous ces cas `&#233;` arrive intact là où `é` arrive en deux caractères de mojibake. Si vous n’avez pas ce problème, n’y touchez pas.

Échapper n’est pas assainir, et les confondre est une faille

Échapper transforme du balisage en texte. Assainir conserve le balisage et en retire les parties dangereuses — la différence entre montrer une balise `<script>` à quelqu’un et lui laisser une balise `<b>` mais pas une `<script>`. Deux opérations différentes, deux modes d’échec différents, et une seule des deux est totale.

Si vous voulez du texte, échappez : il n’y a pas de contournement, et cette page le fait. Si vous voulez un sous-ensemble de HTML, il vous faut un assainisseur avec une liste blanche et un mainteneur actif, et aucune quantité d’échappement ne le remplace. Un outil qui proposerait les deux derrière un interrupteur inviterait surtout au mauvais choix.

Les emoji, et la paire de substitution qui casse les encodeurs

Une chaîne JavaScript est une suite d’unités de seize bits, et tout ce qui dépasse U+FFFF — chaque emoji, une bonne partie des extensions CJK — en occupe deux. Un encodeur qui parcourt la chaîne par index voit ces moitiés séparément et émet deux références numériques, dont aucune n’est un caractère.

La sortie s’affiche alors comme deux glyphes de remplacement et ne peut plus être décodée. Celui-ci parcourt par point de code, donc un emoji devient `&#127757;` et non `&#55356;&#57101;`. Un mot de différence dans l’implémentation, et c’est la différence entre un aller-retour qui fonctionne et un qui ne fonctionne pas.

Les entités françaises que vous n’avez pas besoin d’écrire

Les documentations anciennes recommandent `&eacute;`, `&agrave;` et `&ccedil;` pour les caractères accentués. C’était nécessaire quand un document pouvait être servi en ASCII ; ce ne l’est plus depuis qu’un `<meta charset="utf-8">` suffit, et une page moderne écrit `é` directement.

Le réglage minimal de cette page ne les produit donc pas, et c’est délibéré : un texte français rempli d’entités est trois fois plus long, illisible en relecture, et impossible à rechercher dans le fichier. Le réglage élargi les produit sous forme numérique quand vous en avez vraiment besoin, c’est-à-dire quand quelque chose en aval n’est pas en UTF-8.

L’espace insécable, celle qu’il faut voir

La typographie française demande une espace insécable avant `?`, `!`, `;`, `:` et à l’intérieur des guillemets. Ce caractère est invisible et se copie sans qu’on le remarque, notamment depuis un traitement de texte ou depuis un CMS qui l’insère automatiquement.

Le réglage élargi le rend visible sous forme `&#160;`, ce qui est parfois exactement ce qu’on cherche : une chaîne qui refuse de correspondre à une autre alors qu’elles sont visiblement identiques contient très souvent une insécable là où l’autre a une espace ordinaire. L’échappement sert alors de diagnostic autant que de transport.

Le contexte décide, et il y en a plus qu’un

Échapper ces cinq caractères est correct pour du texte placé entre deux balises, et pour une valeur d’attribut entourée de guillemets. Ce n’est pas suffisant ailleurs : à l’intérieur d’une balise `<script>`, dans une URL passée à un `href`, dans un bloc de style, les règles sont différentes et l’échappement HTML n’y protège pas.

La conséquence est qu’un outil comme celui-ci résout un contexte sur quatre. C’est le contexte le plus fréquent et de loin, mais si vous insérez une valeur dans du JavaScript ou dans une URL, il faut l’encodage propre à ce contexte — et pour l’URL, la page d’encodage d’adresse est à côté.

Échapper à l’écriture ou à l’affichage

À l’affichage. Stockez ce que la personne a réellement écrit, et échappez au moment où le texte est inséré dans une page : le même texte partira peut-être plus tard dans un courriel, un PDF ou une réponse d’API, où les entités HTML sont simplement fausses.

Échapper à l’entrée est la façon dont une base finit remplie de `&amp;amp;`, un caractère par couche accumulée. Et cela ne protège même pas, parce que la valeur peut ensuite être insérée dans un contexte où l’échappement HTML n’a aucun sens. La règle tient en une phrase : échapper appartient à la couche qui rend, pas à celle qui enregistre.

Encoder en entités HTML : questions fréquentes

Quels caractères le réglage par défaut échappe-t-il ?

L’esperluette, les deux chevrons et les deux sortes de guillemets. Ces cinq-là changent la façon dont un document s’analyse ; tout le reste est déjà inerte, et l’échapper n’achète que de la longueur. L’option élargie ajoute tout ce qui dépasse l’ASCII, ce qui relève du transport et non de la correction.

L’échappement me protège-t-il du cross-site scripting ?

Échapper un texte avant qu’il entre dans une page est la bonne défense pour ce contexte — mais seulement s’il a lieu partout où du texte non fiable est inséré, et seulement si le contexte est bien du texte plutôt qu’un attribut dans un script ou une URL. Passer une chaîne dans un outil n’est pas une stratégie ; échapper dans la couche de gabarits en est une.

Pourquoi mon emoji devient-il un seul nombre et non deux ?

Parce que c’est la réponse correcte. Un emoji est un caractère unique au-dessus de U+FFFF, stocké sur deux unités dans une chaîne JavaScript. Les encodeurs qui parcourent par index en émettent deux références, et celles-ci ne peuvent plus être retransformées en quoi que ce soit. Celui-ci parcourt par point de code, donc l’emoji survit à l’aller-retour.

Faut-il échapper les accents français ?

Pas dans une page moderne. Un document servi en UTF-8 affiche `é` directement, et le remplir d’entités le rend trois fois plus long et illisible en relecture. L’option élargie existe pour le cas où quelque chose en aval n’est pas propre en UTF-8, ce qui est un problème de transport et non de correction.

Quelque chose est-il envoyé à un serveur ?

Non. Le remplacement a lieu dans cette page et l’onglet réseau ne montre rien qui parte pendant que vous tapez. Cela compte plus qu’il n’y paraît ici : le texte que les gens échappent est souvent un commentaire de client ou un message de support, c’est-à-dire la donnée de quelqu’un d’autre.

Autres outils