# Cosa non andava in password.es, e adesso sì

> Un sito che passa le giornate a dire come andrebbero fatte le cose deve raccontare quando non le faceva. Ecco cosa abbiamo trovato in casa nostra, con i numeri.

2026-08-31 · David Carrero · password.es
Original: https://password.es/it/blog/cosa-non-andava-in-password-es/

---

Questo blog conta dodici articoli che spiegano come andrebbero fatte le cose: che
la lunghezza conta più dei simboli, che un gestore non è una comodità ma l'unico
modo di rispettare la regola, che una percentuale non dice niente.

Scriverlo è facile. La parte scomoda è guardare il proprio sito con lo stesso
metro. **Lo abbiamo fatto, e tre cose non andavano.** Stanno qui per intero, con
i numeri che le hanno tradite, perché un sito di sicurezza che pubblica solo i
propri successi vale parecchio meno.

## Il controllo si bloccava mentre scrivevi

Il controllo analizza la tua password con [zxcvbn](https://github.com/dropbox/zxcvbn),
una libreria che cerca schemi invece di contare maiuscole. Funziona benissimo e ha
un costo: **gira tutta insieme, sullo stesso thread che disegna la pagina.**
Mentre gira, il browser non può fare altro.

Quel costo cresce in fretta con la lunghezza. Misurato con lo stesso pacchetto che
serve il sito, e con password come quelle che la gente scrive davvero — parole,
anni, `@` al posto di `a`:

| lunghezza | una esecuzione |
|---|---|
| 16 caratteri | 45 ms |
| 20 caratteri | 121 ms |
| 32 caratteri | 273 ms |
| 64 caratteri | 843 ms |
| 128 caratteri | 3.621 ms |

Fin qui, normale. Il problema era quante volte la lanciavamo.

Il campo aveva **due** ascoltatori collegati, `input` e `keyup`. Un tasto normale
li fa scattare entrambi. Così a ogni lettera digitata l'analisi completa girava
**due volte**: 90 ms su una password di 16 caratteri, mezzo secondo su una di 32.

E niente la frenava: né un timer, né un limite di lunghezza, né un thread a parte.
Oltre una ventina di caratteri il browser impiegava più tempo ad analizzare di
quanto tu ne impiegassi a premere il tasto successivo. Le battute si accumulavano
in una coda che non si svuotava più, e **la pagina smetteva di rispondere mentre
scrivevi**. Incollare una password lunga la congelava per secondi.

La correzione sono due modifiche piccole. Abbiamo tolto l'ascoltatore `keyup`,
perché `input` copre già digitazione, incolla, cancellazione e riempimento
automatico del gestore: metà del lavoro sparisce senza cambiare nulla di quello
che vedi. E abbiamo aggiunto un'attesa di 150 millisecondi: mentre scrivi non si
analizza niente, e si analizza appena ti fermi. Nessuno digita così piano da
accorgersene.

Il risultato è identico. `Barcelona1992$` dice sempre le stesse cose: che
«barcelona» sta nel dizionario, che 1992 sembra un anno, e che cade in meno di un
secondo.

## La descrizione era troncata a metà frase in quindici lingue

Questa è più sciocca e più imbarazzante.

La frase che appare sotto il titolo nel motore di ricerca — la meta description —
era **troncata in quindici delle diciotto lingue** del controllo. Si salvavano
solo spagnolo, coreano e giapponese. Qualcuno l'ha tagliata per lunghezza a un
certo punto, ha reciso a metà parola, e dopo nessuno ha guardato.

In tre lingue il taglio è caduto in mezzo a un carattere speciale, quindi quello
che pubblicavamo su Google era questo:

| lingua | cosa servivamo | cosa doveva dire |
|---|---|---|
| portoghese | `…datas e padr&o` | `padrões` |
| turco | `…arıyor ve ger&cced` | `gerçekten` |
| vietnamita | `…chúng tôi tra mật kh&#` | `mật khẩu` |

La cosa notevole è dove stava: sulla **pagina che funziona meglio di tutto il
sito**. Il controllo converte molto meglio del generatore, e lo faceva con la
descrizione rotta. Tutte e quindici sono complete.

Già che c'eravamo, in coreano, giapponese e vietnamita il marchio è passato
dall'inizio alla fine del titolo. Nei risultati il dominio si vede comunque a
parte, quindi aprire con «password.es ·» sprecava solo lo spazio che pesa di più.

## Un bias di uno su cento milioni

Il generatore sceglie ogni carattere con `crypto.getRandomValues()`, la buona
fonte di casualità del browser. Ma per trasformare quel numero enorme in «una
posizione dell'alfabeto» usavamo un resto, e lì c'è una trappola classica: 2³² non
è multiplo di 83, quindi **le prime posizioni dell'alfabeto uscivano un
pochettino più spesso delle ultime**.

Quanto pochettino: con un alfabeto fino a 89 caratteri, dell'ordine di una parte
su cento milioni. Non cambia niente. Non rende la tua password sensibilmente più
debole, nemmeno lontanamente.

L'abbiamo corretto lo stesso, e sono tre righe: si scartano i 45 valori in eccesso
sui 4.294.967.296 possibili e si risorteggia. Su un sito che parla di password,
«è trascurabile» non è una buona ragione per lasciare un bias quando toglierlo
costa così poco.

## Cosa mancava: che il browser facesse rispettare la promessa

Abbiamo un articolo intero che spiega che [la tua password non esce da qui](/it/blog/perche-non-inviamo-la-tua-password/).
Era vero, e comunque era solo una nostra frase: tecnicamente nulla impediva a uno
script iniettato di fare altro.

Ora ogni pagina porta una politica di sicurezza dei contenuti. Le due parti che
contano:

- **Non gira nessuno script che non fosse nella pagina al momento di costruirla.**
  Ogni script legittimo è firmato con la sua impronta; uno iniettato non
  corrisponde e il browser si rifiuta di eseguirlo.
- **`connect-src 'none'`.** Il sito non fa una sola richiesta di rete da
  JavaScript, e adesso è il browser a imporlo. Se un giorno qualcosa provasse a
  mandare da qualche parte ciò che scrivi, non uscirebbe.

La promessa ha smesso di essere una dichiarazione ed è diventata una regola.

## Cosa continua a non andare

**Aggiornamento del 31 agosto.** Le tre cose di questa sezione sono state sistemate lo stesso giorno in cui è uscito l'articolo: le quindici lingue ora descrivono il motore vero, le due scale sono una, e le FAQ del controllo spiegano la faccenda dei simboli. Restano scritte, perché il registro di ciò che non andava vale più della foto di un sito impeccabile.

Qui questo articolo si guadagna il posto.

**Quindici lingue descrivono ancora il controllo come il motore vecchio.** Il
loro testo dice che riproduce la logica classica di PasswordMeter. Non più: quel
motore è stato sostituito perché dava «molto forte» a `Password1!` e bocciava una
frase di cinque parole, che è esattamente il contrario. Spagnolo, coreano e
giapponese sono aggiornati; gli altri quindici no.

**Ci sono due scale diverse nella stessa casa.** La home decide se una password è
forte in base ai bit; il controllo lo decide in base al tempo che costerebbe
romperla. Criteri diversi, e da nessuna parte lo diciamo.

**Generatore e controllo non contano gli stessi simboli**: uno ne usa 27, l'altro
ne suppone 33. La differenza è piccola, ma c'è.

Nessuna delle tre è grave. Tutte e tre sono debito, e preferiscono stare scritte
qui piuttosto che aspettare che le trovi qualcun altro.

## Il registro di questa versione

Siccome il repository non è pubblico, il registro delle modifiche sta qui per
intero. Versione **0.2.0**, del 31 agosto 2026:

**Aggiunto.** Una politica di sicurezza dei contenuti per pagina, con l'impronta
di ogni script. L'articolo su dove sono le tue password salvate, in tutte e
diciotto le lingue. Una coda editoriale che decide cosa si scrive, e che impone
di non pubblicare niente quando si svuota.

**Corretto.** La descrizione del controllo, troncata a metà frase in quindici
lingue, tre delle quali con un carattere spezzato a metà. Il blocco della scheda
mentre scrivevi. Il bias del sorteggio. E la foto che mancava nell'articolo
precedente.

**Cambiato.** Il titolo del controllo in coreano, giapponese e vietnamita. Il
rilascio, che ora scatta quando il sito costruito esiste già e non un minuto
prima. E le traduzioni in vietnamita, hindi e arabo, che smettono di bloccare una
pubblicazione pur restando le più fragili.

---

*Le cifre di questo articolo sono misurate, non stimate: i tempi di zxcvbn con lo
stesso pacchetto che serve il sito e password con parole e sostituzioni; il bias
del sorteggio, calcolato sui 4.294.967.296 valori di un intero a 32 bit. Il motore
del controllo è [zxcvbn](https://github.com/dropbox/zxcvbn), open source.*
