Codifica delle entità HTML vs codifica URL: le differenze fondamentali
La codifica delle entità HTML converte caratteri come <, >, & e " in entità HTML (<, >, &, ") per una visualizzazione sicura nelle pagine web. La codifica URL converte i caratteri nel formato %XX per una trasmissione sicura all'interno degli URL. Proteggono da diversi tipi di attacchi e si utilizzano in contesti differenti.
Che cos'è la codifica delle entità HTML?
La codifica delle entità HTML (chiamata anche escaping HTML) converte i caratteri che hanno un significato speciale in HTML in riferimenti a entità che i browser visualizzano come carattere letterale, invece di interpretarli come markup. I caratteri più importanti da codificare sono <, >, &, " e '.
Senza la codifica HTML, una stringa come <script>alert('XSS')</script> verrebbe eseguita come JavaScript dal browser. Con la codifica, diventa <script>alert('XSS')</script> e viene visualizzata come testo innocuo.
Le entità HTML possono essere scritte in due forme: entità con nome come &, < e ", oppure entità numeriche come &, < e ". Le entità numeriche utilizzano il code point Unicode del carattere e possono rappresentare qualsiasi carattere Unicode.
<!-- Prima della codifica HTML -->
<p>The formula is: x < y & y > z</p>
<!-- Il browser interpreta < come inizio di un tag! -->
<!-- Dopo la codifica HTML -->
<p>The formula is: x < y & y > z</p>
<!-- Il browser visualizza: x < y & y > z -->
<!-- Entità HTML comuni -->
& → & (e commerciale)
< → < (minore di)
> → > (maggiore di)
" → " (virgolette doppie)
' → ' (virgoletta singola / apostrofo)
→ (spazio unificatore)
Che cos'è la codifica URL?
La codifica URL (percent-encoding) converte i caratteri che non sono sicuri negli URL in un segno di percentuale seguito da due cifre esadecimali che rappresentano il valore del byte. È definita dall'RFC 3986 e garantisce che gli URL contengano solo caratteri ASCII validi, trasmissibili in modo sicuro su Internet.
La codifica URL è necessaria perché gli URL hanno una sintassi rigida in cui alcuni caratteri fungono da delimitatori (/, ?, &, #, =). Quando questi caratteri compaiono all'interno dei dati (come i valori dei parametri di query), devono essere codificati per evitare che vengano interpretati come elementi strutturali.
// Esempi di codifica URL
space → %20
& → %26
= → %3D
? → %3F
# → %23
/ → %2F
+ → %2B
// URL completo con parametro di query codificato
https://example.com/search?q=salt%20%26%20pepper
// Il valore di q è "salt & pepper"
Tabella comparativa
| Caratteristica | Codifica delle entità HTML | Codifica URL |
|---|---|---|
| Scopo | Visualizzazione sicura nelle pagine HTML | Trasmissione sicura negli URL |
| Standard | Specifica HTML/WHATWG | RFC 3986 |
| Formato | &name; o &#number; |
%XX (valore esadecimale del byte) |
| Lo spazio diventa | (unificatore) o resta invariato |
%20 o + |
| & diventa | & |
%26 |
| < diventa | < |
%3C |
| Previene | Attacchi XSS, HTML corrotto | URL corrotti, attacchi di injection |
| Contesto | Corpo e attributi del documento HTML | Percorsi URL, query string, frammenti |
| Funzione JS | Nessuna integrata (usa una libreria o le API del DOM) | encodeURIComponent() |
Quando servono entrambe?
Ci sono situazioni comuni in cui servono sia la codifica HTML sia la codifica URL. Il caso più frequente è quando si inserisce un URL all'interno di un attributo HTML, come un attributo href o src. L'URL deve prima essere correttamente codificato con la codifica URL, e in seguito qualsiasi carattere HTML speciale presente nel risultato deve essere codificato con la codifica HTML.
<!-- Passo 1: codifica URL del valore del parametro di query -->
<!-- Valore: "Tom & Jerry" → codificato in URL: "Tom%20%26%20Jerry" -->
<!-- Passo 2: costruisci l'URL -->
<!-- URL: https://example.com/search?q=Tom%20%26%20Jerry -->
<!-- Passo 3: codifica HTML dell'URL per l'uso in un attributo href -->
<a href="https://example.com/search?q=Tom%20%26%20Jerry">
Search for Tom & Jerry
</a>
<!-- In questo caso, le sequenze % non richiedono la codifica HTML -->
<!-- perché % non è un carattere HTML speciale -->
<!-- Ma se l'URL contiene & come delimitatore, DEVE essere codificato in HTML: -->
<a href="https://example.com/search?q=cats&sort=name">
Search cats sorted by name
</a>
<!-- Senza &, il browser potrebbe interpretare &sort come un'entità HTML -->
Nei framework moderni come React, Vue e Angular, la codifica HTML viene gestita automaticamente quando si utilizzano espressioni nei template o JSX. Tuttavia, la codifica URL deve ancora essere eseguita esplicitamente quando si costruiscono URL a partire da dati dinamici.
// React - la codifica HTML è automatica, quella URL no
function SearchLink({ query }) {
// La codifica URL deve essere esplicita
const url = '/search?q=' + encodeURIComponent(query);
// La codifica HTML è automatica in JSX
return <a href={url}>Search for {query}</a>;
// React codifica automaticamente in HTML sia l'href sia il contenuto testuale
}
Prevenzione degli XSS: quale codifica usare e dove
La prevenzione degli attacchi Cross-Site Scripting (XSS) richiede di applicare la codifica corretta in base al contesto in cui viene inserito l'input dell'utente. Utilizzare il tipo di codifica sbagliato in un determinato contesto non offre alcuna protezione.
- Contesto del corpo HTML: usa la codifica delle entità HTML. Questo impedisce che i tag iniettati come
<script>vengano interpretati come markup. - Contesto degli attributi HTML: usa la codifica delle entità HTML e racchiudi sempre i valori degli attributi tra virgolette. Dagli attributi senza virgolette è possibile evadere anche in presenza di codifica HTML.
- Contesto URL (href, src): usa la codifica URL per le parti dinamiche, poi applica la codifica HTML all'intero URL se lo inserisci nell'HTML. Verifica che l'URL inizi con uno schema sicuro (
https:) per prevenire URL di tipojavascript:. - Contesto JavaScript: usa l'escaping delle stringhe JavaScript (JSON.stringify o una libreria dedicata). Né la codifica HTML né la codifica URL sono sufficienti in un contesto JavaScript.
- Contesto CSS: usa l'escaping CSS. La codifica HTML e URL non proteggono dalle injection CSS.
Il principio chiave è: codifica in base al contesto di output, non alla sorgente di input. Un singolo dato inserito dall'utente potrebbe richiedere codifiche diverse a seconda di dove compare nella risposta. Non affidarti mai alla sola validazione dell'input per la prevenzione degli XSS; applica sempre la codifica in output.