Skip to content

Tutto per WordPress, lo sviluppo web — e non solo

🔐 Che tipo di hash usa WordPress

🔐 Che tipo di hash usa WordPress

La password del pannello di amministrazione è l'ultima barriera tra un hacker e il controllo totale del tuo sito. Una password debole o un meccanismo di archiviazione obsoleto trasformano un hosting costoso e un firewall a pagamento in semplici decorazioni.

In oltre vent'anni, WordPress si è evoluto da MD5 a bcrypt di livello enterprise. A partire dalla versione 6.8, l'hashing delle password è diventato moderno fin da subito, senza plugin o soluzioni alternative. Ma ogni proprietario di sito dovrebbe capire esattamente cosa succede alla propria password dopo aver cliccato «Accedi».

Ecco l'intera catena: dall'inserimento della password nel modulo di login fino alla stringa hash nel database. Con codice, filtri e impostazioni specifiche per chi desidera più di quanto offre il core.

💡 Panoramica rapida:

  • WordPress 6.8 e versioni successive esegue l'hashing delle password usando l'algoritmo bcrypt, lo stesso standard adottato da banche e sistemi governativi
  • Gli hash vecchi (MD5, phpass) vengono automaticamente aggiornati a bcrypt al successivo accesso dell'utente; la migrazione è trasparente e non richiede alcun intervento manuale
  • Il filtro wp_hash_password_algorithm consente di passare ad Argon2 con una singola riga di codice, senza bisogno di plugin
  • Il plugin PHP Native Password Hash resta un'opzione valida per le versioni precedenti alla 6.8 e offre una configurazione dettagliata dei parametri di Argon2 tramite wp-config.php

Cos'è l'hashing e perché WordPress ne ha bisogno

L'hashing è una trasformazione crittografica unidirezionale. Da una stringa di qualsiasi lunghezza si ottiene un'«impronta digitale» di dimensione fissa. È matematicamente impossibile invertire un hash per risalire alla password originale; si possono solo provare input diversi e confrontare gli hash risultanti.

Diagramma di hashing delle password in WordPress

A differenza della crittografia, dove i dati possono essere recuperati con una chiave, un hash è un biglietto di sola andata. Quando inserisci una password durante il login, WordPress la passa attraverso la stessa funzione di hash e confronta il risultato con ciò che è memorizzato nel database. Se corrispondono, l'accesso è concesso. In caso contrario, viene negato.

WordPress memorizza gli hash nella tabella wp_users, nel campo user_pass. Se il database subisce una fuga di dati (ed è successo anche a colossi: LinkedIn, Yahoo e Tumblr hanno perso centinaia di milioni di record), un attaccante non ottiene password leggibili ma lunghe stringhe bcrypt. Recuperare la password da una stringa del genere è impossibile. Ma indovinarla tramite un attacco a dizionario è possibile se l'algoritmo è debole o obsoleto. Ecco perché l'evoluzione dell'hashing in WordPress è così importante.

Come WordPress eseguiva l'hashing delle password in passato: MD5 e phpass

Prima della versione 2.5 (2008), WordPress usava MD5 semplice. L'algoritmo trasforma qualsiasi password in un hash a 128 bit composto da 32 caratteri esadecimali. Sembra sicuro, ma MD5 è vulnerabile alle rainbow table (database precalcolati di hash per miliardi di password comuni). Un hacker con accesso al database cerca semplicemente l'hash in una tabella del genere e recupera all'istante la password originale.

A partire dalla versione 2.5, WordPress è passato a phpass, una libreria portabile basata su bcrypt (Blowfish). Aggiungeva un «salt» casuale alla password ed eseguiva il risultato attraverso la funzione di hash più volte (di default, 2^8 = 256 iterazioni). Il salt rendeva inutili le rainbow table: due password identiche per utenti diversi producevano hash diversi. Allo stesso tempo, phpass manteneva la retrocompatibilità con MD5; le vecchie password non si rompevano e venivano aggiornate senza problemi al nuovo formato al momento del login.

Questo è stato sufficiente per molti anni. Ma il settore è andato avanti: l'hardware moderno (GPU farm e ASIC) può provare miliardi di hash al secondo. L'algoritmo bcrypt con un fattore di costo configurabile è diventato lo standard del settore. E a partire da WordPress 6.8, il core lo utilizza in modo nativo.

WordPress 6.8 e bcrypt: cosa è cambiato

Il rilascio di WordPress 6.8 «Cecil» (aprile 2025) ha portato una transizione completa a bcrypt. In precedenza, il core utilizzava la propria classe PasswordHash della libreria phpass; ora chiama la funzione PHP nativa password_hash() con la costante PASSWORD_BCRYPT.

Sicurezza WordPress tramite hashing nativo PHP

Modifiche chiave nella funzione wp_hash_password():

  • bcrypt per impostazione predefinita. Tutte le nuove password vengono sottoposte a hashing tramite password_hash() usando l'algoritmo bcrypt e il fattore di costo impostato dal server PHP (solitamente 10).
  • Migrazione automatica delle vecchie password. Quando un utente effettua il login, WordPress verifica tramite password_needs_rehash() se l'hash necessita di aggiornamento. Il vecchio formato phpass ($P$...) viene sostituito in modo trasparente con bcrypt.
  • Protezione per password lunghe. bcrypt tronca le password più lunghe di 72 byte, riducendo l'entropia. WordPress 6.8 risolve questo problema con un pre-hashing SHA-384 usando la chiave di dominio wp-sha384 e la codifica in base64. Una password di 100 caratteri mantiene tutta la sua forza.
  • Filtri per una configurazione flessibile. Sono comparsi nuovi hook: wp_hash_password_algorithm (selezione dell'algoritmo) e wp_hash_password_options (parametri: cost, memory_cost, threads).

La chiamata a wp_hash_password() nel core di WordPress 6.8 si presenta così:

1function wp_hash_password( $password ) {
2 global $wp_hasher;
3
4 if ( ! empty( $wp_hasher ) ) {
5 return $wp_hasher->HashPassword( trim( $password ) );
6 }
7
8 if ( strlen( $password ) > 4096 ) {
9 return '*';
10 }
11
12 $algorithm = apply_filters( 'wp_hash_password_algorithm', PASSWORD_BCRYPT );
13 $options = apply_filters( 'wp_hash_password_options', array(), $algorithm );
14
15 if ( PASSWORD_BCRYPT !== $algorithm ) {
16 return password_hash( $password, $algorithm, $options );
17 }
18
19 $password_to_hash = base64_encode(
20 hash_hmac( 'sha384', trim( $password ), 'wp-sha384', true )
21 );
22
23 return '$wp' . password_hash( $password_to_hash, $algorithm, $options );
24}

La funzione verifica innanzitutto se la logica di hashing è stata sovrascritta da un plugin esterno (la variabile globale $wp_hasher). Poi rifiuta password più lunghe di 4096 caratteri; tali tentativi di login restituiscono *, rendendo impossibile l'autenticazione. Poi arriva la parte interessante: il filtro wp_hash_password_algorithm determina l'algoritmo. Se la selezione NON è bcrypt, la password viene sottoposta a hashing direttamente. Se viene selezionato bcrypt, la password passa prima attraverso SHA-384 con la chiave wp-sha384, viene codificata in base64 e solo allora viene passata a password_hash(). L'output è un hash con il prefisso $wp, che distingue il bcrypt «WordPress» dal bcrypt standard. Questo è utile per audit del database o integrazioni con sistemi esterni.

Come rafforzare l'hashing con Argon2

bcrypt è un'ottima base di partenza. Il passo successivo è Argon2, il vincitore della Password Hashing Competition del 2015. Argon2 è stato progettato specificamente per resistere agli attacchi GPU: è memory-intensive, e le schede video rappresentano il collo di bottiglia in questo caso.

Esempio di codice per passare WordPress ad Argon2

Opzione 1: l'hook wp_hash_password_algorithm (WordPress 6.8+)

Aggiungi questo codice al file functions.php del tuo tema child o tramite il plugin Code Snippets:

1add_filter( 'wp_hash_password_algorithm', function() {
2 return PASSWORD_ARGON2ID;
3});

In un paio di secondi, WordPress passa ad Argon2ID. Le vecchie password vengono automaticamente ri-sottoposte a hashing quando gli utenti effettuano il login. Il tuo hosting deve supportare Argon2 in PHP; è necessaria la versione 7.3 o successiva per Argon2ID. Puoi verificare la disponibilità chiamando password_algos().

Per una regolazione fine dei parametri, usa l'hook complementare:

1add_filter( 'wp_hash_password_options', function( $options, $algorithm ) {
2 if ( PASSWORD_ARGON2ID === $algorithm ) {
3 return array(
4 'memory_cost' => 65536, // 64 MB
5 'time_cost' => 4,
6 'threads' => 2,
7 );
8 }
9 return $options;
10}, 10, 2 );

Il parametro memory_cost determina quanta memoria l'algoritmo deve utilizzare per calcolare l'hash; più alto è il valore, più difficile diventa il brute-force basato su GPU. time_cost imposta il numero di iterazioni e threads il numero di thread.

Opzione 2: il plugin PHP Native Password Hash

Per le versioni di WordPress precedenti alla 6.8, il plugin PHP Native Password Hash fa la stessa cosa. Sostituisce tutta la logica di hashing con la funzione nativa password_hash(), supporta bcrypt e Argon2 e non ha interfaccia; tutte le impostazioni si configurano tramite costanti in wp-config.php:

1define( 'WP_PASSWORD_HASH_ALGO', PASSWORD_ARGON2ID );
2define( 'WP_PASSWORD_HASH_OPTIONS', [
3 'memory_cost' => 65536,
4 'time_cost' => 4,
5 'threads' => 2,
6] );

Il plugin non viene aggiornato da oltre due anni, ma il suo codice è minimale e stabile. Con WordPress 6.8, la sua funzionalità è integrata nel core, quindi puoi disinstallarlo e usare invece i filtri nativi.

Generatori di hash: cosa funziona oggi

Ci sono situazioni in cui devi generare un hash manualmente: scrivere una password direttamente nel database via phpMyAdmin o migrare utenti da un sistema esterno.

Generatore di hash password WordPress via WP-CLI

Il generatore online di passwordtool.hu, molto usato ai tempi delle vecchie versioni di WordPress, non è più disponibile: il sito ha cambiato proprietà. Alternative funzionanti oggi:

  • WP-CLI: il comando wp user update <id> --user_pass="newpassword" fa tutto correttamente tramite wp_hash_password(). Veloce, sicuro e garantito corretto.
  • Uno script PHP nella root del sito: crea temporaneamente un file con una chiamata a echo wp_hash_password('password'); e cancellalo subito dopo l'uso.
  • Qualsiasi generatore bcrypt online: per esempio, bcrypt.online. Ma ricorda: WordPress 6.8 aggiunge il prefisso $wp e il pre-hashing SHA-384, quindi un hash bcrypt vanilla non funzionerà per l'inserimento diretto nel database.

In pratica, WP-CLI è l'opzione più affidabile.

Come scegliere una password che non verrà craccata

Neanche bcrypt ti salva se la password è admin123. Gli hacker iniziano l'attacco con un brute force a dizionario.

Interfaccia di controllo robustezza password WordPress

Lo strumento zxcvbn di Dropbox, integrato in WordPress per la valutazione delle password nel pannello di amministrazione, rifiuta gli schemi comuni: date di nascita, 123456 e qwerty, nomi di animali domestici. Analizza le password confrontandole con dizionari, layout di tastiera e schemi di sostituzione dei caratteri. Una valutazione "debole" significa che la password può essere indovinata in pochi secondi.

Tre regole pratiche:

  • Parole casuali, non zuppa di caratteri. Una password composta da quattro o cinque parole inglesi scollegate con separatori (per esempio, correct-horse-battery-staple) è più facile da ricordare di Tr0ub4dor&3 e richiede molto più tempo per essere craccata.
  • La lunghezza conta più della complessità. Sedici lettere minuscole casuali offrono un'entropia maggiore di 8 caratteri con simboli speciali. E bcrypt in WordPress 6.8 preserva l'entropia di password di qualsiasi lunghezza ragionevole grazie al pre-hashing SHA-384.
  • Usa un password manager. La memoria umana è uno strumento scarso per gestire una dozzina di password uniche. 1Password è il gold standard a pagamento con piano famiglia, KeePass è open source gratuito con database locale, Bitwarden è la via di mezzo ideale: gratuito, basato su cloud e open source.
Password manager per memorizzare credenziali WordPress

Un password manager genera, memorizza e compila automaticamente le password. Devi solo ricordare una password principale. E se il sito supporta l'autenticazione a due fattori, attivala senza esitazione. Una password più un codice monouso da un'app rende l'accesso praticamente inviolabile.

Video: come funziona l'hashing delle password in WordPress

Una breve spiegazione del meccanismo di hashing, dall'inserimento della password alla memorizzazione nel database di WordPress:

⁉️🤔 Domande frequenti

Le password hashate con il vecchio MD5 funzionano ancora in WordPress 6.8+?

Sì. Quando un utente effettua il login, WordPress rileva il vecchio formato hash, verifica la password usando l'algoritmo precedente e, se tutto corrisponde, aggiorna l'hash a bcrypt in modo trasparente. Non c'è bisogno di eliminare vecchi utenti o forzare il reset delle password.

Il plugin PHP Native Password Hash è necessario su WordPress 6.8 e versioni successive?

No. Tutto ciò che faceva il plugin (hashing tramite password_hash() e supporto Argon2) è ora disponibile tramite i filtri nativi wp_hash_password_algorithm e wp_hash_password_options. Il plugin resta rilevante solo per le versioni precedenti alla 6.8.

Posso tornare da Argon2 a bcrypt?

Tecnicamente sì, cambiando l'algoritmo nel filtro. Ma i vecchi hash Argon2 non verranno riconosciuti e gli utenti dovranno reimpostare le password. Se stai sperimentando con gli algoritmi su un sito live, fai prima un backup completo del database.

bcrypt aiuta se il database viene compromesso?

bcrypt rende il brute force delle password a partire dagli hash trafugati centinaia di migliaia di volte più lento rispetto a MD5. Con un cost factor di 10, un hash su una CPU moderna richiede circa 0,1 secondi per essere calcolato; un miliardo di tentativi richiederebbe anni. Ma se la password è password, verrà trovata alla primissima iterazione di un attacco a dizionario. L'algoritmo protegge le password complesse; niente può salvare quelle deboli.

Come posso verificare che le mie password siano hashate con bcrypt?

Controlla la tabella wp_users via phpMyAdmin. Il campo user_pass per i nuovi utenti (e per quelli che hanno effettuato il login dopo l'aggiornamento alla 6.8) dovrebbe iniziare con il prefisso $wp (il marcatore del nuovo formato bcrypt di WordPress). I vecchi hash phpass appaiono come $P$B.... Per un controllo massivo, esegui questa query SQL: SELECT COUNT(*) FROM wp_users WHERE user_pass NOT LIKE '$wp$%' AND user_pass NOT LIKE '$P$%';. Mostrerà quante password sono bloccate in un formato obsoleto, se ce ne sono.

Cosa fare subito per l'hashing di WordPress

Se il tuo sito WordPress è alla versione 6.8 o successiva, sei già protetto da bcrypt; non devi fare nulla. Il core aggiorna automaticamente i vecchi hash quando gli utenti effettuano il login e la migrazione è completamente trasparente.

Se vuoi usare Argon2, aggiungi il filtro wp_hash_password_algorithm con PASSWORD_ARGON2ID al file functions.php. Prima, verifica che il tuo hosting supporti Argon2: esegui var_dump(password_algos()); tramite uno script di test. La maggior parte dei provider di hosting moderni lo supporta.

Per le versioni precedenti alla 6.8, installa il plugin PHP Native Password Hash; ti fornirà bcrypt o Argon2 senza dover aggiornare il core. E già che ci sei, pianifica un aggiornamento di WordPress: ogni major update chiude decine di vulnerabilità, non solo quelle legate all'hashing.

E cosa più importante, cambia admin123 con qualcosa di decente. Nessun algoritmo può salvarti da un attacco a dizionario se la tua password è tra le prime cento voci della lista rockyou.txt.