Enumerazione utenti WordPress: REST API e URL autore
Enumerazione utenti WordPress: verifica quali nomi di login espone il sito tramite REST API, URL autore, sitemap e errori di accesso, e applica correzioni sicure.
Anche in: English Deutsch Français Español Polski Português Türkçe
In un'installazione WordPress predefinita, i nomi di login si recuperano di solito in meno di un minuto. L'enumerazione degli utenti in WordPress passa da cinque o sei canali integrati: la REST API, i redirect ?author=1, gli URL degli archivi autore, la sitemap degli utenti, i messaggi di errore del login e, in certi casi, i feed e i dati oEmbed. Questo articolo mostra come verificare ogni canale sul proprio sito e come chiuderlo con una correzione mirata, che non compromette l'editor a blocchi.
Che cos'è l'enumerazione degli utenti in WordPress e quanto pesa
Enumerare gli utenti significa raccogliere da un sito nomi di account validi. Un attaccante che sa che esiste mkeller può usare ogni tentativo di password, e ogni password trapelata da altre violazioni, contro un account reale, invece di provare a caso admin, info e test.
Occorre essere chiari su ciò che il nascondere i nomi ottiene: è un rallentamento, non una protezione. A impedire la compromissione di un account sono l'autenticazione a due fattori e la limitazione dei tentativi di accesso, quindi vanno impostate per prime (autenticazione a due fattori per WordPress, protezione dagli attacchi brute force). Poi si chiudono le falle descritte sotto, in quest'ordine: verifica, correzione, nuova verifica.
Verificare il proprio sito: sei punti da cui trapelano i nomi utente
Questi test vanno eseguiti solo su siti propri o di cui si ha la gestione. Conviene farli senza essere autenticati, da terminale o in una finestra privata del browser, perché le sessioni autenticate vedono di più. Sostituire example.com con il proprio dominio.
- REST API. Il core elenca gli utenti che hanno pubblicato contenuti. Il campo da guardare è
slug, cioè lo slug dell'autore, di solito identico al login.
curl -s https://example.com/wp-json/wp/v2/users | grep -o '"slug":"[^"]*"'
curl -s "https://example.com/?rest_route=/wp/v2/users" | grep -o '"slug":"[^"]*"'
- Redirect degli ID autore. WordPress reindirizza
?author=Nall'URL autore in forma leggibile. Provare con 1, 2, 3 e così via.
curl -sI "https://example.com/?author=1" | grep -i '^location'
- HTML del tema. I link all'autore negli articoli e classi CSS come
comment-author-<slug>nei commenti degli utenti registrati.
curl -s https://example.com/a-post/ | grep -oE '/author/[^/"]+/|comment-author-[a-z0-9-]+' | sort -u
- Sitemap degli utenti. Aprire nel browser
https://example.com/wp-sitemap-users-1.xml.
- Errori di login. Su
wp-login.phpinserire prima un nome utente inventato, poi uno reale con password sbagliata. Se i messaggi sono diversi, il modulo conferma quali account esistono. Il modulo di recupero password si comporta allo stesso modo. Bastano due o tre tentativi, così la limitazione dei tentativi non blocca chi sta testando.
- Feed e oEmbed. Il feed mostra i nomi visualizzati in
dc:creator. L'endpoint oEmbed restituisceauthor_nameeauthor_url, e quest'ultimo URL contiene lo slug dell'autore.
curl -s https://example.com/feed/ | grep -i 'dc:creator'
curl -s "https://example.com/wp-json/oembed/1.0/embed?url=https://example.com/a-post/"
| Canale | Test | Cosa rivela |
|---|---|---|
| Utenti REST | /wp-json/wp/v2/users | Slug, nome, ID |
| Redirect autore | /?author=1 | Slug nell'intestazione Location |
| HTML del tema | Markup di articoli e commenti | Slug |
| Sitemap utenti | /wp-sitemap-users-1.xml | URL autore con slug |
| Errori di login | Utente inesistente o password errata | Login validi |
| Feed / oEmbed | dc:creator, author_url | Nome visualizzato, slug |
Chi preferisce un metodo strutturato trova un approfondimento sui test di enumerazione degli account nella OWASP Web Security Testing Guide.
Limitare l'endpoint REST degli utenti solo ai visitatori anonimi
L'intervento deve riguardare soltanto la route degli utenti e soltanto le richieste senza un utente autenticato. L'editor a blocchi usa /wp/v2/users per il selettore dell'autore, e le app mobili e molti plugin lo chiamano con autenticazione. Se la route viene rimossa per tutti, smettono di funzionare.
Creare il file wp-content/mu-plugins/user-enumeration.php. I must-use plugin si caricano automaticamente e non si possono disattivare dalla bacheca. Il filtro rest_endpoints permette di eliminare route prima che vengano servite:
<?php
/**
* Plugin Name: Limit user enumeration
*/
add_filter( 'rest_endpoints', function ( $endpoints ) {
if ( is_user_logged_in() ) {
return $endpoints;
}
unset( $endpoints['/wp/v2/users'] );
unset( $endpoints['/wp/v2/users/(?P<id>[\d]+)'] );
return $endpoints;
} );
Rieseguire il test con curl: ora dovrebbe comparire un errore rest_no_route con stato 404. Poi accedere, aprire un articolo nell'editor e controllare che il pannello dell'autore elenchi ancora gli utenti.
Se si usa un front end headless o un'app che legge i dati degli autori in forma anonima, questo snippet li interrompe. In quel caso conviene esporre solo i campi necessari tramite un endpoint personalizzato. Il riferimento della REST API per gli utenti elenca i dati restituiti dall'endpoint.
Bloccare i redirect degli ID autore e valutare se servono gli archivi autore
Quando qualcuno richiede /?author=2, WordPress individua l'utente e il redirect canonico manda il visitatore a /author/<slug>/. L'intestazione Location rivela lo slug, e uno script può scorrere gli ID da 1 a 50 in pochi secondi.
Aggiungere questo codice sotto il primo snippet, nello stesso mu-plugin. Viene eseguito prima del redirect canonico e risponde con un semplice 404 alle richieste anonime che contengono il parametro author, così nessuna intestazione Location svela lo slug:
add_action( 'template_redirect', function () {
if ( is_user_logged_in() ) {
return;
}
if ( isset( $_GET['author'] ) ) {
wp_die( 'Not found.', '', array( 'response' => 404 ) );
}
}, 1 );
Ripetere il test con curl -sI "https://example.com/?author=1": ora si dovrebbe ottenere un 404 e nessuna intestazione Location.
In un blog aziendale con un solo autore, o in un sito senza pagine autore pubbliche, si può fare un passo in più e disattivare gli archivi autore. La maggior parte dei plugin SEO ha un'impostazione apposita, e anche alcuni temi. Il limite va detto con onestà: se il tema stampa link "di <autore>" su ogni articolo, lo slug resta comunque nell'HTML. Se ne occupano le due sezioni successive.
Rimuovere la sitemap degli utenti dove nessuno ne ha bisogno
Le sitemap del core, introdotte con WordPress 5.5, includono un provider per gli utenti che elenca ogni archivio autore. Pochi siti aziendali ne traggono un vantaggio. Il filtro wp_sitemaps_add_provider lo rimuove:
add_filter( 'wp_sitemaps_add_provider', function ( $provider, $name ) {
if ( 'users' === $name ) {
return false;
}
return $provider;
}, 10, 2 );
Aprire di nuovo /wp-sitemap-users-1.xml: ora dovrebbe restituire un 404. Se un plugin SEO sostituisce le sitemap del core, questo filtro non incide sul suo output. In tal caso cercare nelle impostazioni della sitemap del plugin una sitemap degli autori e disattivarla da lì.
Differenziare nome visualizzato e slug autore dal nome di login
In Utenti > Profilo impostare un Nickname e sceglierlo in Mostra pubblicamente come. Questo copre i feed, author_name di oEmbed e le indicazioni "di ...".
Qui c'è però un'insidia. Lo slug dell'autore (user_nicename) viene generato dal login alla creazione dell'account e non cambia quando si modifica il nome visualizzato. Gli articoli possono riportare "Redazione" mentre l'URL continua a mostrare /author/mkeller/. Si corregge con WP-CLI:
wp db export before-nicename.sql
wp user list --fields=ID,user_login,user_nicename,display_name
wp user update 2 --user_nicename=editorial-team
Usare lettere minuscole, cifre e trattini, e mantenere ogni slug univoco. I vecchi URL degli autori cambiano: occorre mettere in conto qualche 404 oppure aggiungere un redirect, se quelle pagine avevano traffico.
Per i nuovi account, evitare come login admin, il nome dell'azienda e il nome del dominio. Se il problema dipende anche da account vecchi o condivisi, conviene prima fare pulizia: sicurezza dei ruoli utente in WordPress.
Messaggi di errore generici al login
Il filtro login_errors sostituisce i messaggi mostrati nella schermata di accesso con un unico testo neutro:
add_filter( 'login_errors', function () {
return '<strong>Error:</strong> The login details are incorrect.';
} );
Così però si eliminano anche i messaggi utili, come il suggerimento sui campi vuoti, e gli utenti ricevono meno indicazioni. Né il sito diventa davvero opaco: il modulo di recupero password continua a comportarsi in modo diverso per gli account validi, perché un account reale porta alla schermata "controlla la tua email". Alcuni plugin aggiungono propri moduli di accesso, e la pagina Il mio account di WooCommerce ha messaggi propri. Va considerata una misura di coerenza, non un controllo efficace.
Cosa non impedisce il nascondere i nomi utente
Gli attaccanti provano nomi comuni e indirizzi email indipendentemente dal fatto che il sito li riveli, e WordPress accetta l'indirizzo email come login. Il credential stuffing, che ripropone coppie di nome utente e password provenienti da altre violazioni, non richiede alcuna enumerazione. Un elenco di utenti perfettamente nascosto non serve a nulla contro una password riutilizzata.
Per il sito di una piccola impresa l'ordine è quindi questo:
- Autenticazione a due fattori per ogni amministratore ed editor (guida alla configurazione).
- Limitazione dei tentativi di accesso e una decisione su XML-RPC (protezione dagli attacchi brute force).
- Le correzioni anti-enumerazione descritte sopra, verificate con i comandi curl.
- Inserire il risultato nella verifica periodica (checklist di sicurezza per WordPress).
Il plugin Security Audit & Compliance di secaudit.eu include la limitazione dei tentativi di accesso e il rate limiting della REST API per gli utenti anonimi, e la sua scansione di hardening segnala i problemi di configurazione, così si vede che cosa resta aperto → secaudit.eu
Il passo successivo: eseguire oggi sul proprio sito i sei test di questo articolo, annotare i risultati e correggere i canali che mostrano un nome di login reale.
FAQ
Bloccare /wp/v2/users compromette l'editor a blocchi?
No, se la restrizione vale solo per le richieste anonime, come nello snippet sopra. L'editor invia richieste autenticate, quindi il selettore dell'autore continua a funzionare. Rimuovere la route anche per gli utenti connessi lo comprometterebbe.
«admin» è ancora un rischio se ho la 2FA?
Molto meno. Con la 2FA, una password indovinata da sola non basta per entrare. Ma admin attira tentativi continui, che riempiono i log e possono far scattare blocchi, quindi vale comunque la pena sostituirlo.
Devo rinominare il login stesso e come si fa?
WordPress non ha un pulsante per cambiare il nome di login. Si crea un nuovo amministratore con un login neutro e la 2FA, si accede con quell'account, poi si elimina il vecchio account e, quando WordPress lo chiede, si assegnano i contenuti al nuovo. Deve sempre restare almeno un amministratore funzionante. I dettagli sono in sicurezza dei ruoli utente in WordPress.
Controlla il tuo sito
Security Audit & Compliance è il plugin WordPress di secaudit.eu: cerca malware, spam nascosto, file core modificati e codice vulnerabile, e collega i risultati all’art. 32 del GDPR, all’art. 21 della NIS2 e alla OWASP Top 10.
Scopri cosa controlla il plugin