A01. Seguretat en WordPress
Contingut
- 1 Enunciat
- 2 Procediment
- 2.1 Comprovar i/o actualitzar a la darrera versió de PHP
- 2.2 Comprovar que tenim Wordpress i plugins actualitzats. Sinó actualitza’ls
- 2.3 Passwords forts i permisos d’usuari. Canviar usuari ADMIN
- 2.4 Instal·lar plugin per fer còpies de seguretat o programar el vostre propi sistema. Instal·lar un WAF (Firewall)
- 2.5 Desactivar l’edició de fitxers
- 2.6 Desactivar execució de PHP a diversos directoris del vostre Wordpress
- 2.7 Limitar intents d’inici de sessió
- 2.8 Instal·lar un CAPTCHA
- 2.9 Canviar prefix de les taules de la base de dades Wordpress
- 2.10 Protegir pàgines wp-admin i wp-login
- 2.11 Protegir l’arxiu wp-config
- 2.12 Deshabilitar el directori de Browsing o Índex
- 2.13 Deshabilitar XML-RPC de Wordpress
- 2.14 Desconnectar usuaris per inactivitat
- 2.15 Ocultar la versió de Wordpress
- 2.16 Canviar permisos d’arxiu
- 2.17 Prevenir hotlinking
Enunciat
En aquesta activitat heu de posar en pràctica cadascuna de les solucions explicades per millorar la seguretat al nostre Wordpress. Heu de fer servir el Wordpress instal·lat al mòdul anterior o tornar a instal·lar una nova màquina amb Wordpress.
Solucions a implantar:
- Comprovar i/o actualitzar a la darrera versió de PHP
- Comprovar que tenim Wordpress i plugins actualitzats. Sinó actualitza’ls.
- Passwords forts i permisos d’usuari. Canviar usuari ADMIN.
- Instal·lar plugin per fer còpies de seguretat o programar el vostre propi sistema. Instal·lar un WAF (Firewall)
- Desactivar l’edició de fitxers
- Desactivar execució de PHP a diversos directoris del vostre Wordpress
- Limitar intents d’inici de sessió
- Instal·lar un CAPTCHA
- Canviar prefix de la bases de dades Wordpress
- Protegir pàgines wp-admin i wp-login
- Protegir l’arxiu wp-config
- Deshabilitar el directori de Browsing o Índex
- Deshabilitar XML-RPC de Wordpress
- Desconnectar usuaris per inactivitat
- Ocultar la versió de Wordpress
- Canviar permisos d’arxiu
- Prevenir HOTLINKING
Procediment
Comprovar i/o actualitzar a la darrera versió de PHP
Per a comprovar la versió:
php -v
wordpressm09:~ # php -v PHP 7.3.1 (cli) ( NTS ) Copyright (c) 1997-2018 The PHP Group Zend Engine v3.3.1, Copyright (c) 1998-2018 Zend Technologies
Veiem que està instal·lada la versió 7.3.1
Al moment de fer aquesta pràctica, segons la pàgina web de PHP, la versió més recent és la 7.3.2. Podem considerar que és una versió actualitzada i no farem res.
Comprovar que tenim Wordpress i plugins actualitzats. Sinó actualitza’ls
Des de l'apartat de Tauler →Actualitzacions podem veure un resum de l'estat del Wordpress, plugins i temes. Tal com veiem a la captura, estan els 3 apartats updated.
Passwords forts i permisos d’usuari. Canviar usuari ADMIN
Des de l'apartat Usuaris →Tots els usuaris podem veure una llista dels usuaris del Wordpress. En el meu cas, al moment de la instal·lació, ja vaig definir un usuari administrador que no tingués el nom admin i té una contrasenya forta.
Instal·lar plugin per fer còpies de seguretat o programar el vostre propi sistema. Instal·lar un WAF (Firewall)
He aprofitat la instal·lació i la configuració del plugin BackWPUp de M09.
Com a Firewall instal·laré el plugin Wordfence Security
Desactivar l’edició de fitxers
Haurem d'editar l'arxiu de configuració del Wordpress; en el meu cas es troba a /srv/www/htdocs/wp-config.php
. Definirem una variable de PHP nova que farà que Wordpress deshabiliti la pestanya d'edició de fitxers des de la web. Afegirem a l'última línia, per conveniència, la següent definició de constant de PHP.
define('DISALLOW_FILE_EDIT', true);
Desactivar execució de PHP a diversos directoris del vostre Wordpress
Com que fem servir el servidor web Apache, podem tirar d'arxius .htaccess en directoris concrets on volguem definir noves condicions: per exemple, permetre accés des de IPs concretes, permetre o denegar l'accés a diversos arxius en funció de l'extensió, etc.
En aquest cas, se'ns demana prohibir l'execució d'arxius *.php
. No tindria sentit aplicar aquesta restricció a tots els directoris, ja que llavors Wordpress no funcionaria at all. El que tindria sentit seria aplicar-ho en directoris multimèdia com ara wp-content/uploads
ja que allà no tindrien perquè servir-se arxius PHP i podria ser un lloc on algun atacant pogués camuflar-hi codi maliciós.
Per a aplicar aquestes restriccions tenim 2 opcions:
- Mitjançant arxius .htaccess en els directoris.
- Ideal si no tenim accés a la configuració del servidor, com en el cas d'haver contractat un servidor privat virtual compartit (VPS).
- Mitjançant directives
<Directory>
en l'arxiu de configuració del servidor web.
- Millor si tenim accés al servidor com a administradors i podem editar els arxius de configuració de l'Apache. És més segur que el primer mètode ja que l'arxiu de configuració no es troba en directoris accessibles des de la web, de manera que és immune a vulnerabilitats relacionades amb fallades de seguretat del servidor web.
La directiva necessària en el primer cas serà
<Files *.php> deny from all </Files>
i la situarem al directori a partir d'on volem aplicar la norma (és recursiu en els directoris fills a partir del directori que conté l'arxiu).
En l'altre cas, afegirem la mateixa directiva però entre tags <Directory>
<Directory "/srv/www/htdocs/wp-content/uploads" <Files *.php> deny from all </Files> </Directory>
Limitar intents d’inici de sessió
Podem trobar diversos plugins que afegeixin aquesta funcionalitat; però el mateix Wordfence Security té aquesta opció a l'apartat All options del seu menú:
Veiem que a l'apartat de Brute force protection podem definir un límit de fallades en l'usuari/contrasenya (per defecte 20 vegades en 4 hores). També hi ha una opció interessant que és bloquejar intents d'inici de sessió des d'adreces IP en funció de noms d'usuari que nosaltres definim; per exemple, si no fem servir admin o similar per a l'administrador, podem definir-lo perquè un atacant quan provi d'iniciar sessió amb usuari admin, es bloquegi automàticament i no tingui possibilitat de llançar cap altre atac o intent.
Instal·lar un CAPTCHA
Buscarem el plugin No CAPTCHA reCAPTCHA de Google. En el meu cas, perquè l'havia utilitzat en pàgines Wordpress abans i recordo que funcionava bé.
Després d'instal·lar i activar, trobarem per configurar les claus al menú de l'esquerra a Configuració →Login noCAPTCHA
Necessitem un compte de Google per a tenir unes claus que ens lliguin a aquest widget que afegirem a la nostra pàgina de login. Seguirem el link que se'ns subministra des del plugin mateix. Omplirem les dades d'acord al que correspongui i ens assegurarem de marcar l'opció reCAPTCHA v2 ja que és l'única que suporta aquest plugin.
Enviarem i se'ns subministraran els parells de claus per a afegir al plugin i acabar-ne la configuració i posar-lo en marxa.
Una vegada desat, si per exemple obrim una finestra privada nova al navegador i anem a la pàgina de login, veurem que ens apareix la comprovació del CAPTCHA per a iniciar sessió.
Canviar prefix de les taules de la base de dades Wordpress
Per a fer això, ens ajudarem de l'eina gràfica de gestió de bases de dades MySQL/MariaDB PHPMyAdmin; de manera que des d'una interfície gràfica, poguem fer els canvis a les taules mentre tenim el lloc web en mode de manteniment i llavors editar l'arxiu de configuració de Wordpress per a fer-hi constar el nou prefix de les taules.
Per a posar el Wordpress en mode de manteniment crearem un arxiu amb el nom .maintenance
a l'arrel d'instal·lació del Wordpress amb el següent contingut
<?php $upgrading = time(); ?>
De manera que ningú pugui accedir i, per tant, wordpress no faci cap consulta a la BBDD, eliminant així la possibilitat de corrompre les dades mentre fem el canvi.
De no tenir PHPMyAdmin instal·lat:
zypper in phpMyAdmin
I reiniciarem el servei web per a carregar la nova configuració per a poder accedir a PHPMyAdmin
systemctl reload apache2
- Anirem ara a la URL http://wordpressm09.asix/phpMyAdmin/ i farem login amb l'usuari root de MariaDB.
- Desplegarem a l'esquerra la base de dades wordpress i comprovarem el prefix de les taules
En aquest cas, en el moment de la instal·lació, ja es va triar un prefix diferent al default que és wp_
. Tot i això, seria també més segur fer servir una cadena de caràcters totalment aleatòria per a mitigar la possibilitat que un atacant pogués endevinar-la.
Protegir pàgines wp-admin i wp-login
Ho farem amb autenticació HTTP de manera que es demani un usuari i una contrasenya aliens a Wordpress per a accedir a aquestes pàgines. Primer de tot crearem un arxiu .htpasswd
on hi figuraran els usuaris i els hashos de les contrasenyes:
wordpressm09:~ # htpasswd -c /opt/.htpasswd guillem New password: Re-type new password: Adding password for user guillem
Això crearà un nou arxiu a la ruta /opt
de manera que ara, poguem afegir als directoris wp-admin
i wp-login
un arxiu que faci que el servidor web demani autenticació bàsica per a poder servir el contingut d'aquests directoris al client que ho demana.
Crearem llavors un arxiu .htaccess
a dins de /srv/www/htdocs/wp-admin
wordpressm09:~ # nano /srv/www/htdocs/wp-admin/.htaccess
AuthType Basic AuthName "Accés restringit" AuthUserFile /opt.htpasswd Require user guillem
Si ara accedim a la URL que hem protegit, se'ns demanarà un usuari i contrasenya.
Protegir l’arxiu wp-config
Per a protegir-lo podem optar per a treure'l de la ruta des d'on es serveix la web i deixar allà un arxiu PHP amb el mateix nom que simplement faci una inclusió de l'arxiu de configuració real que es trobi en una altra ruta del sistema de fitxers i, fins i tot, amb un nom totalment diferent.
Ho farem de la següent manera:
- Copiarem l'arxiu original a una altra ruta i li canviarem el nom; per exemple
/opt/wallpaper.png
- Editarem l'arxiu original i hi posarem el següent contingut:
require '/opt/wallpaper.png';
I aquests passos els executaríem amb les següents comandes:
wordpressm09:~ # cp /srv/www/htdocs/wp-config.php /opt/wallpaper.png wordpressm09:~ # nano /srv/www/htdocs/wp-config.php
D'aquesta manera, deixem camuflat en una ruta no default l'arxiu bàsic de configuració del CMS; de manera que un atacant no pugui veure el contingut o modificar-lo, ja que l'arxiu que es troba a la ruta on el necessita Wordpress és només una inclusió (obligatòria →require) del contingut d'un arxiu que no es troba al directori base del servidor web.
Deshabilitar el directori de Browsing o Índex
Això, tal com el punt 6, podem fer-ho mitjançant arxiu .htaccess o bé des de la configuració d'Apache. Per comoditat ho faré de la primera manera encara que, per seguretat, si tenim accés al servidor, és millor amb directives del servidor web.
nano /srv/www/htdocs/.htaccess # BEGIN WordPress <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule> # END WordPress Options -Indexes
Deshabilitar XML-RPC de Wordpress
Per defecte està habilitat i si accedim a http://wordpressm09.asix/xmlrpc.php veiem que se'ns respon
Haurem d'afegir una nova directiva al fitxer .htaccess
de l'arrel per a prohibir l'accés a aquest fitxer per part dels clients web
nano /srv/www/htdocs/.htaccess <Files "xmlrpc.php"> Require all denied </Files>
Desconnectar usuaris per inactivitat
Farem servir el plugin Inactive Logout
La configuració d'aquest plugin es troba a Configuració →Inactive User Logout. Entre diversos paràmetres, podem definir el temps màxim d'inactivitat abans de desconnectar l'usuari automàticament, i també el missatge que li apareixerà en pantalla quan es detecti una inactivitat propera al temps màxim; de manera que l'usuari pugui mantenir la sessió o tancar-la.
Ocultar la versió de Wordpress
Si mirem el codi font de la pàgina principal de Wordpress, per exemple, veurem que hi ha una línia amb un contingut semblant a aquest
Això és públic i podria ser analitzat per atacants per a saber quines vulnerabilitats té aquesta versió concreta i poder triar un atac adequat a aquesta versió. Si modifiquem la funció que genera aquest string on s'explicita la versió, podem enganyar, confondre o ocultar la versió del nostre Wordpress de manera que sigui més difícil saber a quines vulnerabilitats està exposat.
Haurem d'editar l'arxiu functions.php
del nostre tema. En el meu cas /srv/www/htdocs/wp-content/themes/graphene/functions.php
i afegirem el contingut següent al final
function remover_version() { return '<meta name="generator" content="WordPress 0.0" />'; } add_filter('the_generator', 'remover_version');
Després de fer aquest canvi
Canviar permisos d’arxiu
WordPress recomana que l'arxiu de configuració només sigui llegit pel servidor web, de manera que podem ajustar els permisos a un 400 de manera que tampoc pugui ser escrit:
chmod 400 /srv/www/htdocs/wp-config.php
Si comprovem ara els permisos veurem que
-r-------- 1 wwwrun www 42 23 feb 12:31 /srv/www/htdocs/wp-config.php
Només té permisos de lectura; suficients per a fer funcionar la web.
Prevenir hotlinking
El hotlinking és fer referència a una imatge a la nostra web però que es demana des d'un altre servidor; de manera que si algú fa hotlinking d'una imatge del nostre WordPress, per a cada petició que rebi "l'atacant", tindrem nosaltres una petició perquè s'ha referenciat des de la nostra pàgina. Això pot suposar un increment de l'ample de banda i de les peticions que puguin commprometre la disponibilitat del nostre servidor; de manera que és interessant evitar que se serveixin arxius de la nostra pàgina des de dominis (referrers) que no siguin la nostra pròpia pàgina.
Això es pot aconseguir amb un conjunt de directives a l'arxiu .htaccess
del directori base del nostre Wordpress
RewriteEngine on RewriteCond %{HTTP_REFERER} !^$ RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?wordpressm09.asix [NC] RewriteRule \.(jpg|jpeg|png|gif)$ https://www.unwantedwitness.or.ug/wp-content/uploads/2017/04/ERROR-404.jpg [NC,R,L]
D'aquesta manera, si jo des d'un altre servidor web faig referència a una imatge des d'aquella ruta però demanant-la des d'un domini que no correspongui al del propi servidor, mostraré una imatge d'error 404 (que, paradoxalment, faré servir hotlinking per a mostrar-la)
Faré la prova intentant mostrar una imatge des del servidor web del meu Fedora hotlinkejada des de la màquina virtual de wordpress. He creat un arxiu que serviré per la web amb el contingut
<html> <head> <title>Prova Hotlink wordpress</title> </head> <body> <h1>Prova hotlink</h1> <img src="http://wordpressm09.asix/wp-content/uploads/2019/02/cropped-abstract.jpg" alt="Prova portada hotlinkejada des de Wordpress" /> </body> </html>
Tot i això, amb la configuració mostrada al principi d'aquest apartat, no funciona perquè això està pensat per a dominis públics registrats en DNS de manera que, per a fer la prova, he modificat l'arxiu .htaccess
per a fer-hi constar l'adreça IP en comptes d'un nom de domini que no està registrat
RewriteEngine on RewriteCond %{HTTP_REFERER} !^$ RewriteCond %{HTTP_REFERER} !^http://192.168.57.3 [NC] RewriteRule \.(jpg|jpeg|png|gif)$ https://www.unwantedwitness.or.ug/wp-content/uploads/2017/04/ERROR-404.jpg [NC,R,L]
Aleshores, si accedeixo a http://localhost per a veure la imatge de portada del meu wordpress, llançant la petició a ell, em trobo el següent
És el resultat esperable, ja que es reescriu la petició i es deriva cap a una altra URL, en aquest cas, d'una imatge d'error 404.