Sicurezza WP: sicurezza di wp-admin | cambiare l'URL di login, limitare i login, XML-RPC

Informativa sull'affiliazione v3.1
Informativa sull'affiliazione v3.2 (solo mobile)

La sicurezza di wp-admin è l'insieme delle impostazioni che bloccano gli attacchi brute force contro l'area di amministrazione e la schermata di login di WordPress. Controllando i log degli accessi di un server Nginx + Apache che gestisce diversi siti WordPress, ho visto che le richieste automatiche verso xmlrpc.php continuavano ad arrivare anche dopo aver cambiato l'URL di login, così ho aggiunto anche un limite di richieste a livello di server.

1️⃣ Perché wp-admin e wp-login.php vengono attaccati

Il fatto che l'indirizzo di amministrazione di WordPress sia noto è un punto debole, ma puoi compensarlo rafforzando la sicurezza. Tutti i siti WordPress usano lo stesso /wp-admin/ e lo stesso [wp-login.php], e se apri /wp-admin/ senza aver effettuato l'accesso vieni portato alla schermata di login di [wp-login.php].

Gli attacchi arrivano come brute force, inserendo ripetutamente nomi utente e password in questa schermata di login. Per questo la sicurezza di wp-admin consiste prima nel fermare i tentativi di login e solo dopo nel nascondere l'indirizzo.

I due ingressi al login di WordPress
Accesso dal browser
/wp-admin/
Senza accesso, rimanda alla schermata di login (302)
wp-login.php
Schermata di login · inserire nome utente e password
App · richieste automatiche
xmlrpc.php
Nome utente e password inviati con una richiesta POST, senza schermata di login
Non passa dalla schermata di login
Con system.multicall più password in una sola richiesta · l'indirizzo resta lo stesso anche se cambi l'URL di login
Stesso controllo di nome utente e password
Entrambi gli ingressi verificano l'account con la stessa funzione di autenticazione di WordPress
Gli attacchi brute force entrano dall'ingresso che resta aperto. Il cambio dell'URL di login vale solo per l'ingresso in alto, quindi xmlrpc.php va chiuso a parte oppure va limitato il numero di richieste.

2️⃣ Effetti e limiti del cambio dell'URL di login

Se cambi l'URL di login con un plugin di sicurezza, il [wp-login.php] predefinito restituisce un errore 404 e gli attacchi automatici che continuano a bussare all'indirizzo predefinito non arrivano nemmeno alla schermata di login. Il nuovo indirizzo va comunicato a parte a chi ha un account da amministratore.

🧭 Ingressi al login di WordPress
Diagramma esplicativo
⬜ Nessun plugin
🛡️ Hide My WP
🚪 Ingresso di login
/wp-login.php · /wp-admin/Stesso indirizzo su ogni WordPress
Schermata di login404
/newloginIndirizzo cambiato · lo conoscono solo gli amministratori
Schermata di login
POST /xmlrpc.phpVerifica la password senza schermata di login
Risponde alla verifica della passwordDisattivato 405
Misurato su un sito di test · richieste senza accesso
→
🤖 Attacchi automatici
Ingressi in cui provare password su un indirizzo noto
2
1
Nessuno
Senza plugin le password si possono provare in due punti: [wp-login.php], uguale su ogni sito WordPress, e [xmlrpc.php], che verifica la password senza schermata di login.
Dopo il cambio dell'URL di login, [wp-login.php] e /wp-admin/ restituiscono 404, ma [xmlrpc.php] continua a rispondere se nome utente e password sono corretti.
Se disattivi anche XML-RPC, le richieste di login a [xmlrpc.php] finiscono con la risposta che il servizio XML-RPC è disattivato e non è più possibile provare password su un indirizzo noto.

Questo metodo richiede poco lavoro, ma se dimentichi il nuovo indirizzo non riesci più a entrare nell'area di amministrazione e devi disattivare il plugin rinominandone la cartella via FTP o dal file manager. Se il sito è gestito da più persone, conviene annotare l'indirizzo in un unico posto.

3️⃣ Limitare i tentativi di login e autenticazione a due fattori

Anche con l'URL di login cambiato, se il nuovo indirizzo si viene a sapere i tentativi di indovinare la password continuano. Il core di WordPress non ha un limite ai login falliti: per quante volte inserisci una password sbagliata, si riapre sempre la stessa schermata di login.

🧭 Limitare i tentativi di login e autenticazione a due fattori
Diagramma esplicativo
⬜ Nessun plugin
🛡️ Plugin di sicurezza
🔑 Login dallo stesso IP
1ºPassword sbagliata
Di nuovo la schermata di loginNe restano 3
2ºPassword sbagliata
Di nuovo la schermata di loginNe restano 2
3ºPassword sbagliata
Di nuovo la schermata di loginNe resta 1
4ºPassword sbagliata
Di nuovo la schermata di loginBloccato per 20 min
5ºBloccatoPassword sbagliataLogin · richieste XML-RPC
Di nuovo la schermata di loginAnche xmlrpc.php 403
Inserimento passwordPassword corretta
Schermata del codice
Authentication Code6 cifre dall'app di autenticazione · cambia ogni 30 s
Area di amministrazione
Attaccante che conosce solo la passwordNon conosce il codice
Si ferma alla schermata del codice
Misurato su un sito di test · richieste consecutive dallo stesso IP
→
🤖 Attacchi automatici
Si possono continuare a provare password?
Nessun limite
Bloccato al 4º
Si ferma al codice
Senza plugin, anche inserendo sei volte una password sbagliata dallo stesso IP, si riapre ogni volta la stessa schermata di login.
Con il limite ai tentativi di login attivo, a ogni errore vedi quanti tentativi restano e al 4º errore quell'IP non può accedere per 20 minuti. Durante il blocco anche le richieste a xmlrpc.php finiscono con un 403.
Con l'autenticazione a due fattori attiva, anche con la password giusta l'area di amministrazione si apre solo dopo aver inserito l'[Authentication Code] di 6 cifre che l'app di autenticazione genera ogni 30 secondi.

Un plugin che limita i tentativi di login blocca per un certo tempo l'IP che supera il numero consentito, mentre l'autenticazione a due fattori, anche con la password corretta, chiede in più un codice dall'app di autenticazione sul telefono. Quando attivi l'autenticazione a due fattori, conserva anche i codici di backup da usare se perdi il telefono.

4️⃣ Chiudere xmlrpc.php

[xmlrpc.php] è un secondo ingresso che riceve nome utente e password senza passare dalla schermata di login, e con il metodo [system.multicall] si possono provare più password in una sola richiesta.

Nei log degli accessi di un server Nginx + Apache che gestisce diversi siti WordPress, il 13 ottobre tra le 0:00 e le 9:50 sono arrivate a [xmlrpc.php] 2.250 richieste POST. Provenivano da 22 IP e lo User-Agent si spacciava per Jetpack e WordPress.com.

Se non usi l'app mobile di WordPress né Jetpack, blocca le richieste a [xmlrpc.php] nella configurazione di Nginx oppure usa l'opzione per disattivare XML-RPC del plugin di sicurezza.

# Dentro il blocco server — rifiuta le richieste a xmlrpc.php
location = /xmlrpc.php {
    deny all;
}

Con questa impostazione tutte le richieste GET e POST a [xmlrpc.php] finiscono con un 403 senza arrivare a PHP. La disattivazione di XML-RPC del plugin di sicurezza rifiuta solo le richieste che richiedono il login, mentre il file continua a rispondere: per ridurre anche le esecuzioni di PHP conviene bloccarlo in Nginx.

5️⃣ Bloccare sul server: accesso di amministrazione limitato per IP e limite di richieste

Se gestisci il sito solo da un IP fisso, il metodo più sicuro è consentire [wp-login.php] e /wp-admin/ in Nginx solo a quell'IP. Non va bene se l'IP di casa o dell'ufficio cambia spesso.

Bloccare tutto /wp-admin/ può sembrare la soluzione, ma funzioni lato visitatore come la ricerca o il carrello inviano spesso richieste a [admin-ajax.php], quindi quel file va lasciato aperto.

# Dentro il blocco server — sopra il location che gestisce PHP
location = /wp-login.php {
    allow 203.0.113.10;   # Il tuo IP fisso per la gestione
    deny all;
    # Qui sotto copia le impostazioni del location che gestisce PHP
}

Se apri [wp-login.php] da un IP diverso da quello indicato ottieni un 403, mentre dall'IP indicato si apre la schermata di login. Dentro il location devi copiare così come sono le impostazioni PHP del sito (fastcgi_pass ecc.), altrimenti la schermata di login non funziona correttamente.

Se non puoi fissare l'IP, puoi applicare un limite di richieste alle richieste PHP dei visitatori non connessi; come l'ho fissato a 30 al minuto, perché le richieste automatiche non si prendano le risorse del server, è spiegato nell'articolo Avviso php-fpm max_children dedicato all'argomento.

# Blocco http — conta per IP solo le richieste senza cookie di login
map $http_cookie $php_anon_key {
    default                 $binary_remote_addr;
    "~*wordpress_logged_in" "";
}
limit_req_zone $php_anon_key zone=php_anon:10m rate=30r/m;

# Dentro il location che gestisce PHP
limit_req zone=php_anon burst=60 nodelay;
limit_req_status 429;

Quando un singolo IP non connesso invia richieste PHP di fila, vengono elaborate fino alla 61ª e poi viene restituito un 429; le richieste con cookie di login non vengono contate. Se la cache di pagina risponde senza passare da PHP, i normali visitatori che sfogliano le pagine non incappano in questo limite.

ℹ️ Informativa sull'affiliazione
I contenuti di questo sito includono link di affiliazione. Se un visitatore acquista un prodotto o un servizio tramite uno di questi link, il sito riceve una commissione dal venditore. In questo processo l'importo pagato dall'acquirente (durante le promozioni l'importo scende↓) non aumenta. Prezzi, sconti e disponibilità indicati si riferiscono al momento della stesura e possono differire da quelli reali: prima di acquistare verifica sempre presso il venditore. I prodotti vengono scelti e valutati secondo criteri propri, e le commissioni non influiscono sull'ordine di presentazione né sul contenuto delle valutazioni.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Dimostra di essere umano: 6   +   2   =