Référence6 min de lecture

Encodage des entités HTML vs encodage d'URL : les différences essentielles

L'encodage des entités HTML convertit des caractères comme <, >, & et " en entités HTML (&lt;, &gt;, &amp;, &quot;) pour un affichage sûr dans les pages web. L'encodage d'URL convertit les caractères au format %XX pour une transmission sûre dans les URL. Ils protègent contre différents types d'attaques et s'utilisent dans des contextes distincts.

Qu'est-ce que l'encodage des entités HTML ?

L'encodage des entités HTML (aussi appelé échappement HTML) convertit les caractères qui ont une signification particulière en HTML en références d'entités que les navigateurs affichent comme le caractère littéral au lieu de les interpréter comme du balisage. Les caractères les plus importants à encoder sont <, >, &, " et '.

Sans encodage HTML, une chaîne comme <script>alert('XSS')</script> serait exécutée comme du JavaScript par le navigateur. Avec l'encodage, elle devient &lt;script&gt;alert(&apos;XSS&apos;)&lt;/script&gt; et s'affiche comme du texte inoffensif.

Les entités HTML peuvent s'écrire sous deux formes : les entités nommées comme &amp;, &lt; et &quot;, ou les entités numériques comme &#38;, &#60; et &#34;. Les entités numériques utilisent le point de code Unicode du caractère et peuvent représenter n'importe quel caractère Unicode.

<!-- Avant l'encodage HTML -->
<p>The formula is: x < y & y > z</p>
<!-- Le navigateur interprète < comme le début d'une balise ! -->

<!-- Après l'encodage HTML -->
<p>The formula is: x &lt; y &amp; y &gt; z</p>
<!-- Le navigateur affiche : x < y & y > z -->

<!-- Entités HTML courantes -->
&amp;   → &   (esperluette)
&lt;    → <   (inférieur à)
&gt;    → >   (supérieur à)
&quot;  → "   (guillemet double)
&#39;   → '   (guillemet simple / apostrophe)
&nbsp;  →     (espace insécable)

Qu'est-ce que l'encodage d'URL ?

L'encodage d'URL (percent-encoding) convertit les caractères qui ne sont pas sûrs dans les URL en un signe pourcentage suivi de deux chiffres hexadécimaux représentant la valeur de l'octet. Il est défini par la RFC 3986 et garantit que les URL ne contiennent que des caractères ASCII valides pouvant être transmis en toute sécurité sur Internet.

L'encodage d'URL est nécessaire parce que les URL ont une syntaxe stricte où certains caractères servent de délimiteurs (/, ?, &, #, =). Lorsque ces caractères apparaissent dans les données (comme les valeurs des paramètres de requête), ils doivent être encodés pour éviter qu'ils ne soient interprétés comme des éléments structurels.

// Exemples d'encodage d'URL
space     → %20
&         → %26
=         → %3D
?         → %3F
#         → %23
/         → %2F
+         → %2B

// URL complète avec un paramètre de requête encodé
https://example.com/search?q=salt%20%26%20pepper
// La valeur de q est "salt & pepper"

Tableau comparatif

Caractéristique Encodage des entités HTML Encodage d'URL
Objectif Affichage sûr dans les pages HTML Transmission sûre dans les URL
Standard Spécification HTML/WHATWG RFC 3986
Format &name; ou &#number; %XX (valeur d'octet en hexadécimal)
L'espace devient &nbsp; (insécable) ou laissé tel quel %20 ou +
& devient &amp; %26
< devient &lt; %3C
Empêche Attaques XSS, HTML cassé URL cassées, attaques par injection
Contexte Corps du document HTML et attributs Chemins d'URL, chaînes de requête, fragments
Fonction JS Aucune native (utiliser une bibliothèque ou les API du DOM) encodeURIComponent()

Quand a-t-on besoin des deux ?

Il existe des situations courantes où l'on a besoin à la fois de l'encodage HTML et de l'encodage d'URL. Le cas le plus fréquent est celui où l'on place une URL à l'intérieur d'un attribut HTML, comme un attribut href ou src. L'URL doit d'abord être correctement encodée en URL, puis tout caractère HTML spécial présent dans le résultat doit être encodé en HTML.

<!-- Étape 1 : encoder en URL la valeur du paramètre de requête -->
<!-- Valeur : "Tom & Jerry" → encodée en URL : "Tom%20%26%20Jerry" -->

<!-- Étape 2 : construire l'URL -->
<!-- URL : https://example.com/search?q=Tom%20%26%20Jerry -->

<!-- Étape 3 : encoder l'URL en HTML pour l'utiliser dans un attribut href -->
<a href="https://example.com/search?q=Tom%20%26%20Jerry">
  Search for Tom &amp; Jerry
</a>

<!-- Dans ce cas, les séquences % n'ont pas besoin d'encodage HTML -->
<!-- car % n'est pas un caractère HTML spécial -->

<!-- Mais si l'URL contient & comme délimiteur, il DOIT être encodé en HTML : -->
<a href="https://example.com/search?q=cats&amp;sort=name">
  Search cats sorted by name
</a>
<!-- Sans &amp;, le navigateur pourrait interpréter &sort comme une entité HTML -->

Dans les frameworks modernes comme React, Vue et Angular, l'encodage HTML est géré automatiquement lorsque vous utilisez des expressions de template ou du JSX. Cependant, l'encodage d'URL doit toujours être effectué explicitement lors de la construction d'URL à partir de données dynamiques.

// React - l'encodage HTML est automatique, pas l'encodage d'URL
function SearchLink({ query }) {
  // L'encodage d'URL doit être explicite
  const url = '/search?q=' + encodeURIComponent(query);

  // L'encodage HTML est automatique dans JSX
  return <a href={url}>Search for {query}</a>;
  // React encode automatiquement en HTML l'attribut href et le contenu textuel
}

Prévention des attaques XSS : quel encodage utiliser et où

La prévention des attaques de type Cross-Site Scripting (XSS) exige d'appliquer le bon encodage en fonction du contexte où l'entrée utilisateur est placée. Utiliser le mauvais type d'encodage dans un contexte donné n'offre aucune protection.

  • Contexte du corps HTML : utilisez l'encodage des entités HTML. Cela empêche les balises injectées comme <script> d'être interprétées comme du balisage.
  • Contexte d'attribut HTML : utilisez l'encodage des entités HTML et mettez toujours les valeurs d'attributs entre guillemets. On peut s'échapper des attributs non entre guillemets même avec un encodage HTML.
  • Contexte d'URL (href, src) : utilisez l'encodage d'URL pour les parties dynamiques, puis encodez toute l'URL en HTML si vous la placez dans du HTML. Vérifiez que l'URL commence par un schéma sûr (https:) pour empêcher les URL javascript:.
  • Contexte JavaScript : utilisez l'échappement de chaînes JavaScript (JSON.stringify ou une bibliothèque dédiée). Ni l'encodage HTML ni l'encodage d'URL ne suffisent dans un contexte JavaScript.
  • Contexte CSS : utilisez l'échappement CSS. L'encodage HTML et l'encodage d'URL ne protègent pas contre l'injection CSS.

Le principe clé est le suivant : encodez pour le contexte de sortie, et non pour la source d'entrée. Une même donnée saisie par l'utilisateur peut nécessiter des encodages différents selon l'endroit où elle apparaît dans la réponse. Ne comptez jamais uniquement sur la validation des entrées pour prévenir les attaques XSS ; appliquez toujours un encodage en sortie.

Articles connexes

Essayez nos outils gratuits