Glossario

Cosa sono i Nonce in WordPress? I token di sicurezza spiegati

5 agosto 2026

Un nonce in WordPress è un token di sicurezza che viene allegato a moduli, link e richieste AJAX affinché WordPress possa verificare che la richiesta sia stata avviata intenzionalmente da uno specifico utente autenticato. Il nome arriva dalla crittografia e sta per number used once, ma qui è leggermente fuorviante: un nonce di WordPress non è un numero, non viene usato una volta sola ed è tecnicamente un hash legato all'utente, alla sessione e a una singola azione precisa. Resta valido fino a 24 ore. La minaccia principale da cui i nonce difendono è il cross-site request forgery (CSRF), un attacco in cui una pagina malevola invia silenziosamente una richiesta sfruttando la tua sessione autenticata, per esempio per eliminare un articolo o modificare un'impostazione. I nonce funzionano, ed è proprio per questo che l'errore di sicurezza più comune si trova dall'altra parte: un nonce dimostra l'intenzione, non il permesso. Il codice di un plugin che controlla il nonce ma dimentica la verifica delle capacità con current_user_can() è una delle fonti più frequenti di vulnerabilità WordPress pubblicate.

Cos'è un nonce? Un nome che inganna un po'

In crittografia un nonce è un valore usato esattamente una volta e mai più, ed è questo a renderlo utile contro gli attacchi di replay. WordPress ne ha preso in prestito il nome, ma non la definizione rigorosa. Un nonce di WordPress è un hash breve generato da quattro ingredienti: l'azione a cui appartiene, l'ID e il token di sessione dell'utente corrente, la finestra temporale attuale e le chiavi segrete del tuo wp-config.php. Quella costruzione ha tre conseguenze pratiche:

  • Un nonce è personale. Un token generato per un utente non supera la validazione per nessun altro utente, quindi non può essere condiviso né sottratto da una pagina pubblica.
  • Un nonce è specifico per azione. Un token creato per l'azione delete-post_42 non vale nulla per delete-post_43 né per qualsiasi altra operazione. Ecco perché scrivere un nome di azione generico nel codice indebolisce l'intero meccanismo.
  • Un nonce è riutilizzabile entro la sua durata. Lo stesso token viene validato tutte le volte che vuoi per un massimo di 24 ore. WordPress lo documenta esplicitamente, quindi il nonce da solo non protegge dal replay di una richiesta che l'attaccante abbia già intercettato.

La documentazione ufficiale per sviluppatori WordPress è piacevolmente onesta su tutto questo e descrive i nonce come uno strato di difesa, non come un sistema di sicurezza completo.

Da quali attacchi proteggono i nonce di WordPress? Il CSRF spiegato

L'attacco per cui i nonce esistono è il cross-site request forgery. Lo scenario: sei autenticato nella tua amministrazione WordPress in una scheda del browser. In un'altra scheda apri una pagina del tutto estranea, controllata da un attaccante. Quella pagina contiene un modulo nascosto o un tag immagine che punta al tuo sito, per esempio una richiesta per disattivare un plugin o creare un utente. Poiché il browser invia automaticamente i tuoi cookie WordPress a ogni richiesta verso il tuo dominio, la richiesta arriva pienamente autenticata e WordPress la eseguirebbe senza battere ciglio. Non hai cliccato nulla, non hai visto nulla e il tuo sito ha appena guadagnato un nuovo amministratore.

I nonce spezzano questo attacco all'ultimo passaggio. La pagina malevola può falsificare la richiesta, ma non può conoscere il nonce corrente per il tuo utente e per quell'azione, perché il token compare soltanto dentro le pagine che WordPress genera per te. La richiesta falsificata arriva senza un nonce valido, la verifica fallisce e WordPress si ferma con la famosa schermata bianca che chiede: sei sicuro di voler fare questo?

Quanto dura un nonce di WordPress? Il sistema dei tick

WordPress divide il tempo in tick di dodici ore. Quando un nonce viene verificato, WordPress accetta i token del tick corrente e di quello precedente, ed è da qui che nasce la durata massima di 24 ore. Le funzioni di verifica ti dicono perfino in quale metà ti trovi: restituiscono 1 se il nonce è stato generato nelle ultime dodici ore e 2 se ha tra le dodici e le 24 ore, mentre restituiscono false se non è valido o è scaduto.

La durata si può modificare con il filtro nonce_life, che alcune configurazioni orientate alla sicurezza usano per accorciare la finestra:

// Riduce la durata del nonce a 4 ore
add_filter( 'nonce_life', function () {
	return 4 * HOUR_IN_SECONDS;
} );

Durate più brevi riducono la finestra di replay, ma fanno anche scadere più in fretta le pagine in cache che contengono nonce incorporati, il che è un problema concreto sui siti con caching aggressivo delle pagine. Se una pagina in cache serve un nonce più vecchio di 24 ore, ogni visitatore riceve un token che non potrà mai essere validato. È il motivo classico per cui le funzionalità AJAX su siti WordPress fortemente cachati smettono misteriosamente di funzionare per alcuni visitatori.

Come creare un nonce in WordPress

WordPress mette a disposizione tre funzioni di supporto per generare i nonce, una per ciascun posto in cui un token vive di solito:

// 1. In un modulo: aggiunge un campo input nascosto più un campo referer
wp_nonce_field( 'save_settings_action', 'my_plugin_nonce' );

// 2. In un URL: aggiunge ?_wpnonce=... a un link
$url = wp_nonce_url( admin_url( 'admin.php?page=my-plugin&delete=42' ), 'delete-item_42' );

// 3. Token grezzo, per esempio da passare a JavaScript
$nonce = wp_create_nonce( 'my_ajax_action' );

Il primo argomento è sempre l'azione, ed è qui che la cura ripaga. Una stringa di azione come delete-item_42, che include l'ID dell'oggetto, produce un token che funziona esattamente e solo per quell'elemento. Un'azione generica e pigra come my_nonce condivisa in tutto un plugin significa che un unico token trapelato o prevedibile sblocca ogni operazione che il plugin offre.

Come verificare un nonce: wp_verify_nonce, check_admin_referer e check_ajax_referer

La verifica dispone di una funzione di basso livello e di due wrapper di comodo che incontrerai molto più spesso nel codice reale:

// Basso livello: restituisce 1, 2 o false, non interrompe mai
if ( ! wp_verify_nonce( $_POST['my_plugin_nonce'], 'save_settings_action' ) ) {
	return; // stop, richiesta non valida
}

// Schermate di amministrazione: verifica e interrompe con una pagina di errore
check_admin_referer( 'save_settings_action', 'my_plugin_nonce' );

// Gestori AJAX: stessa idea per le richieste ad admin-ajax.php
check_ajax_referer( 'my_ajax_action', 'security' );

I wrapper interrompono l'esecuzione in caso di fallimento, che di solito è quello che vuoi in cima a un gestore. La funzione di basso livello wp_verify_nonce() ti restituisce invece il valore, così puoi rispondere con un errore JSON corretto in un contesto API. Qualunque variante usi, la verifica deve stare prima che l'azione venga eseguita, non dopo: sembra ovvio ed è comunque un bug ricorrente nei changelog dei plugin.

I nonce nella REST API e nelle richieste AJAX

La REST API di WordPress usa lo stesso meccanismo con un nome di azione fisso. Per ogni richiesta che si basa sull'autenticazione tramite cookie, WordPress si aspetta un nonce creato per l'azione wp_rest, consegnato nell'header di richiesta X-WP-Nonce. Gli script registrati nel modo standard lo ottengono automaticamente: wp_localize_script() o il più recente bundle wp.apiFetch trasmettono il token, e ogni richiesta REST autenticata lo porta con sé senza che lo sviluppatore ci debba pensare.

// Passaggio di un nonce REST al tuo JavaScript
wp_localize_script( 'my-app', 'myAppData', array(
	'restUrl' => esc_url_raw( rest_url( 'my-plugin/v1/' ) ),
	'nonce'   => wp_create_nonce( 'wp_rest' ),
) );

// In JavaScript: invialo come header
fetch( myAppData.restUrl + 'items', {
	method: 'POST',
	headers: { 'X-WP-Nonce': myAppData.nonce, 'Content-Type': 'application/json' },
	body: JSON.stringify( { title: 'Nuovo elemento' } ),
} );

Senza quell'header la REST API tratta la richiesta come non autenticata, anche se il browser ha inviato cookie di accesso validi. È una scelta deliberata: è esattamente la protezione CSRF descritta sopra, applicata all'API.

Perché un nonce non è un controllo dei permessi

Questa è la cosa più importante da capire sui nonce ed è la parte che nell'ecosistema dei plugin va storta con regolarità. Un controllo del nonce superato dimostra due cose: la richiesta è nata da una pagina generata da WordPress e appartiene all'utente a cui il token è stato rilasciato. Non dimostra che quell'utente sia autorizzato a fare ciò che la richiesta chiede. Un sottoscrittore può avere un nonce perfettamente valido, perché WordPress rilascia volentieri nonce a ogni utente autenticato, e alcuni token funzionano perfino per visitatori che non hanno effettuato alcun accesso.

Il codice di un gestore corretto si pone quindi sempre due domande separate:

// Intenzione: è una richiesta autentica di questo utente?
check_admin_referer( 'save_settings_action', 'my_plugin_nonce' );

// Permesso: questo utente è autorizzato a farlo?
if ( ! current_user_can( 'manage_options' ) ) {
	wp_die( 'Permessi insufficienti.' );
}

I database delle vulnerabilità sono pieni di ciò che accade quando la seconda domanda viene saltata. Broken access control e CSRF si collocano stabilmente tra le categorie più comuni nei CVE dei plugin WordPress, e gran parte di quelle voci si riduce a un gestore che ha controllato un nonce, o nulla del tutto, invece di una capacità. Se leggi un bollettino su un plugin che parla di qualsiasi utente autenticato poteva modificare le impostazioni o di autorizzazione mancante, dietro c'è di solito questo schema.

Errori comuni con i nonce in temi e plugin

  • Controllo del nonce al posto del controllo delle capacità. Il classico, descritto sopra. Servono entrambi i controlli, rispondono a domande diverse.
  • Un unico nonce generico per tutto. Una singola stringa di azione in tutto il plugin trasforma un token ristretto in una chiave universale.
  • Nonce nelle pagine in cache. Le cache di pagina intera servono token oltre la loro durata di 24 ore, rompendo silenziosamente moduli e AJAX per alcuni visitatori. Il caching per frammenti o il recupero separato del nonce risolvono il problema.
  • Verificare dopo aver agito. Il controllo deve essere la prima cosa che il gestore fa.
  • Fidarsi di un nonce come prova di identità per utenti non autenticati. I nonce per visitatori senza sessione sono più deboli per costruzione, dato che la componente utente dell'hash è vuota.
  • Esporre i nonce negli URL. I token aggiunti ai link finiscono nei log del server, nella cronologia del browser e nell'header Referer. Per le azioni distruttive, le richieste POST con wp_nonce_field() sono la sistemazione migliore.

Come InspectWP ti aiuta a riconoscere le conseguenze

Dall'esterno non puoi vedere se un plugin verifica correttamente i suoi nonce, ma puoi vederne le conseguenze quando diventano pubbliche. InspectWP rileva plugin e temi di un sito WordPress analizzato insieme alle loro versioni e li confronta con i dati sulle vulnerabilità note, e le falle di tipo CSRF e di autorizzazione mancante esattamente come quelle descritte in questo articolo costituiscono una quota rilevante di quelle voci. Se un report segnala un plugin installato con una vulnerabilità pubblicata, la soluzione è quasi sempre la stessa e piacevolmente semplice: aggiornare. Con i report automatici pianificati, quel ciclo di rilevare, capire e aggiornare procede di continuo invece che quando qualcuno se ne ricorda.

Controlla subito il tuo sito WordPress

InspectWP analizza il tuo sito WordPress per problemi di sicurezza, problemi SEO, conformità GDPR e prestazioni — gratuitamente.

Analizza gratis il tuo sito