WordPress e alcuni consigli per migliorare la sicurezza (3)
da Massimo Della Rovere · pubblicato il 21 Agosto, 2014 · modificato il 13 Agosto, 2016

Con questo articolo completiamo la guida che riguarda i consigli sulla sicurezza in ambiente WordPress. Nella prima parte abbiamo visto gli aspetti generali e le varie soluzioni adottate, nella seconda parte abbiamo visto più gli aspetti che riguardavano la parte di amministrazione e adesso vi proponiamo dei consigli per integrare la sicurezza in modo più avanzato. Come già detto, ricordiamoci sempre di non eseguire le modifiche sul sito ufficiale ma usiamo sempre un’ambiente di test.

Consiglio (13) – Bloccare l’accesso ad alcuni file

Abbiamo già visto la tecnica di bloccare l’accesso ad alcuni file nel consiglio (3), a questo elenco aggiungerei altri file e alcune estensioni che possono essere usate per ottenere informazioni importanti che potrebbero essere usate in un’attacco al nostro sito web. Ad esempio durante alcuni test è possibile che nelle directory standard vengono generati dei file di log che contengono messaggi di debug e/o informazioni private, la cosa grave è che la maggior parte delle volte sono accessibili tramite HTTP.

Quindi per ovviare a questo inconveniente, sarebbe meglio bloccare alcune estensioni che possono indicare file di log, script e configurazioni di plugin. Per eseguire questa operazioni dobbiamo sempre intervenire nel nostro file (.htaccess) e inserire queste nuove regole prima di quelle standard che riguardano WordPress. Personalmente le istruzione che riguardano i <file> o <filematch> le inserisco sempre a inizio file.

# Protezione del file con estensioni che non devono
# essere visualizzate con un richiamo HTTP/HTTPS

<FilesMatch "\.(htaccess|htpasswd|ini|log|sh)$">
  Order Allow,Deny
  Deny from all
</FilesMatch>

Un’altro file che consiglio di bloccare, in quanto sempre presente nelle cronache che riguardano la scoperta di nuove vulnerabilità, è lo script per le richieste XML-RPC, mi raccomando fatelo solo nel caso in cui non usate questa funzione, quindi quando non usate l’app di WordPress da smartphone e plugin che usano questa tecnica. Per definire questa nuova regola aggiungiamo alle istruzioni presenti nel consiglio (3) il blocco del file chiamato (xmlrpc.php) come segue: (vi riporto tutto il blocco).

# Protezione file che non devono essere letti in HTTP
# Qui blocco alcuni file PHP del core e altri che danno informazioni 

RewriteRule ^readme.html(.*)        [R=404,L]
RewriteRule ^license.txt(.*)        [R=404,L]
RewriteRule ^licenza.txt(.*)        [R=404,L]
RewriteRule ^xmlrpc.php(.*)         [R=404,L] // Aggiungere questo
RewriteRule ^wp-content/(.*)\.php$  [R=404,L]
RewriteRule ^wp-includes/(.*)\.php$ [R=404,L]

Se trovate altre estensioni da bloccare con <filematch> o altri file singoli presenti nella directory radice di WordPress, potete aggiungerli con la stessa tecnica riportata, anzi se pensate che ci siano delle estensioni da implementare scrivetemi sui commenti, che se sono importanti aggiorno la documentazione in questione.

Consiglio (14) – Protezione enumerazioni utenti

In WordPress esiste una tecnica abbastanza semplice per scoprire gli utenti presenti in anagrafica, infatti basta richiamare la home page con il parametro (?author=) e tentare tutti i progressivi che vogliamo. Per ogni tentativo saremo dirottati sulla pagina utente da dove potremmo calcolare lo slug e il nome dell’utente trovato. Questa tecnica viene utilizzata anche da WP-SCAN che vi ho presentato in un’articolo precedente.

ruby wpscan.rb --url http://localhost/wordpress --enumerate u

[+] Enumerating usernames ...
[+] Identified the following 3 user/s:
+----+---------+---------------------+
| Id | Login   | Name                |
+----+---------+---------------------+
| 1  | massimo | My Plugin - massimo |
| 2  | utente  | My Plugin - utente  |
| 3  | autore  | My Plugin - autore  |
+----+---------+---------------------+

Se vogliamo bloccare questa tecnica dobbiamo disabilitare le richieste di questo tipo e dirottarle alla nostra home come se non fosse stato specificato nessun parametro, questa tecnica è valida solo se usiamo i permalink attivati (praticamente quasi sempre), se però non usate i permalink allora non dovete seguire questo consiglio.

# Protezione contro la enumerazione degli utenti presenti
# nel database di wordpress tramite chiamata URL?author

RewriteCond %{REQUEST_URI}  ^/$
RewriteCond %{QUERY_STRING} (^|&)author=([0-9]*)
RewriteRule ^(.*)$ http://%{SERVER_NAME}/? [L,R=301]

Su questo codice voglio aggiungere due considerazioni importanti: nella condizione che riguarda la %{REQUEST_URI} ho specificato la directory radice in quanto quasi tutte le installazioni partono da qui, però ci sono casi come ad esempio il mio blog che hanno una cartella chiamata (tech), in questo caso bisognerebbe specificare ^/tech/$. L’altra considerazione riguarda il redirect finale dove bisogna specificare il path esatto della nostra home page e indicare il protocollo giusto utilizzato, come HTTP o HTTPS.

Consiglio (15) – Utilizzare autenticazione a due passaggi

Molti già conosceranno questa tecnica in quanto utilizzata da Google per proteggere i propri account, infatti chi ha già abilitato questa funzione sa che per eseguire il login in google bisogna inserire utente e password e subito dopo una password a tempo che può essere spedita via SMS o generata tramite l’applicazione Google Authenticator.

Quindi se avete WordPress e uno smartphone potete anche voi applicare la stessa forma di sicurezza ad un vostro sito web. Per risolvere questo aspetto abbiamo sviluppato un plugin apposito che si chiama Google for WordPress e che potete scaricare in modo del tutto gratuito dal repository ufficiale di wordpress.org.

Login

Vi abbiamo consigliato di usare il nostro plugin in quanto l’implementazione di questa funzionalità non è semplicissima, però questo non significa che sia impossibile. Quindi se volete procedere su questa strada, scaricate il plugin e guardate la tecnica utilizzata direttamente dai sorgenti, una volta appresi i passaggi potete creare il codice da applicare al vostro tema o al vostro plugin. (lavorate sempre in ambiente di test)

Consiglio (16) – Disattivare il CRON dal core

Come abbiamo visto nel consiglio (3) e nel consiglio (13) dobbiamo sempre cercare di disabilitare il più possibile gli accessi diretti ai file. Ad esempio sulla directory radice abbiamo disattivato tutti i file PHP eccetto il login, i commenti e il cron. Infatti questi elementi sono richiamati per svolgere delle funzioni che non possiamo disattivare.

Però se utilizziamo un server dedicato o un servizio di hosting in cui è possibile svolgere alcune operazioni avanzate, possiamo trovare delle soluzioni alternative e bloccare l’accesso diretto anche a queste risorse. Ad esempio per la funzione CRON di WordPress possiamo disabilitare l’esecuzione nel core e schedularla nel sistema operativo. Per vedere i dettagli di questa operazione leggete l’articolo “WordPress CRON” cercando la sezione che viene chiamata “Disattivare la funzione dal core”.

Una volta che siamo riusciti ad implementare la tecnica riportata nell’articolo indicato, possiamo procedere a bloccare l’accesso anche a questo file. Vi riporto il codice presente nel consiglio (3) e la modifica che deve essere apportata:

# Protezione dei file che non devono essere letti in HTTP
# Blocco tutti i file PHP meno le azioni di login, cron e commenti.

RewriteCond %{REQUEST_URI} !^/wp-(login|cron|comments-post)\.php$
RewriteRule ^wp-([_0-9a-zA-Z-]+)\.php [R=404,L]

# Modificare le istruzione precedenti in questo modo
# Viene negato l'accesso anche al file wp-cron.php

RewriteCond %{REQUEST_URI} !^/wp-(login|comments-post)\.php$
RewriteRule ^wp-([_0-9a-zA-Z-]+)\.php [R=404,L]

Su questo aspetto sto preparando anche un’articolo per disattivare l’accesso al file dei commenti, infatti basta utilizzare una modalità AJAX durante l’inserimento di un nuovo commento al posto del metodo standard. Questo non solo risolve il problema di accesso ma diminuisce con molta probabilità tantissimi commenti SPAM.

Consiglio (17) – Proteggere account amministratore

Durante la fase di installazione viene creato anche l’utente admin con cui possiamo amministrare il nostro sito. Nelle ultime versioni rilasciate possiamo scegliere il nome dell’utente (admin) con uno di nostra fantasia, il problema vero però risiede nel fatto che il nome utente è facilmente reperibile, in quanto corrisponde sempre al codice utente (1) e quindi cambiare solo lo (slug) risolve solo in piccola parte il problema.

Una buona soluzione sarebbe quella di creare un nuovo utente amministratore, nel caso di installazione multisite un nuovo super user, rinominare quello precedente e cambiare il ruolo come sottoscrittore, aggiungere un filtro alla fase di login per forzare un’errore di autenticazione incondizionato a prescindere dalle credenziali inserite.

(1) Creazione  amministratore: questa operazione la potete eseguire direttamente dalla pagina di amministrazione che riguarda gli utenti. Il processo cambia a seconda se ci troviamo in un’installazione standard o multisite, nel primo caso dobbiamo creare un nuovo utente ad esempio (nuovoadmin) e assegnargli i privilegi di amministratore, nel secondo caso dobbiamo prima crearlo a livello di network come super user e solo dopo associarlo ai siti desiderati come utente amministratore.

(2) Rinominare admin precedente: una volta che abbiamo creato un nuovo admin e fatto i test necessari possiamo rinominare quello precedente. Purtroppo in WordPress non esiste un’operazione nativa per rinominare un’utente esistente, quindi dobbiamo usare un comando SQL che ci permetta di raggiungere questo risultato.

UPDATE wp_users SET user_login    = 'nuovoadmin' WHERE ID=1;
UPDATE wp_users SET user_nicename = 'nuovoadmin' WHERE ID=1;

Dopo aver controllato che l’operazione è stata eseguita, entrate in admin con il nuovo utente e cambiate il ruolo come sottoscrittore al vecchio amministratore.

(3) Filtro di controllo su Login: adesso per complicare un po’ le cose, possiamo creare un filtro a livello di autenticazione e fare in modo che il controllo fallisca sempre a fronte dell’utente (1) anche se eventualmente le credenziali fossero giuste. In questo modo manteniamo il vecchio utente attivo ma impossibilitato ad eseguire il login.

// Definizione funzione per controllare id utente=1 e
// ritornare un errore qualsiasi siano state le credenziali

function my_dummy_signon($user,$username,$password) {
  if (isset($user->ID) and $user->ID == 1) return null; 
    else return $user;
}

// Aggiungo alla fase di autenticazione la nostra funzione
// Questo codice possiamo inserirlo nel tema o in un plugin

add_filter('authenticate','my_dummy_signon',30,3);

Una volta che abbiamo configurato questo scenario vi consiglio di non usare mai questi utenti come autori degli articoli che verranno inseriti. In questa maniera risulterà molto più difficile trovare il nome dell’account che deve essere inserito nel login.

Consiglio (18) – Usare SSH2 per le installazioni e gli update

È usanza comune indicare nei permessi dei file di WordPress l’opzione di scrittura da parte del server Web. Questo per avere la possibilità di aggiornare le versioni dal pannello di controllo senza troppi passaggi. In realtà questo tipo di configurazione porta alcuni problemi e consiglio di cambiarla. Il processo completo di questa soluzione lo trovate in un articolo  “Configurare SSH2 e disabilitare i permessi“.

Indice generale degli articoli correlati

1 Commento

  1. Il consiglio 18 che avevo implementato a suo tempo non funziona più dopo il passaggio ad apache 2.4 con PHP versione 7.0, ti risulta qualcosa in merito? esiste una soluzione per risolverlo? ho già cercato su google ma niente.

condividi