Recientemente se ha dado a conocer una vulnerabilidad en el sistema de autenticación de usuarios para los sitios con WordPress, que básicamente consiste en lo siguiente:
- La vulnerabilidad afecta tanto a sitios en WordPress.com como instalaciones propias.
- Al acceder a la administración de tu sitio, WordPress crea una cookie que le permite validarte como un usuario que ha iniciado sesión.
- Una gran cantidad de sitios con WordPress no funciona sobre HTTPS, por lo que la cookie se envía como texto plano.
- Un atacante puede interceptar esa cookie, insertarla en su navegador, y luego hacerse pasar por el usuario que ha iniciado sesión. Esto es particularmente fácil en situaciones donde hay transmisiones “abiertas” de datos, por ejemplo en un café donde la conexión no tiene contraseña.
- La cookie sigue siendo válida aun cuando el usuario cierre su sesión, por lo que podrías ingresar a tu administrador, cerrar la sesión, y el atacante aun tendría acceso.
- El tiempo de expiración de la cookie es de 3 años en blogs de WordPress.com y 14 días en instalaciones propias.
Ahora pasemos a lo importante, ¿cómo evitarlo?
En primer lugar, la opción más sencilla pero seguramente inefectiva es la abstinencia: simplemente, evitar acceder a la administración de WordPress en redes no confiables. Pero como estamos hablando de seguridad, y en este sentido no se puede ser demasiado paranoico, desechemos esta opción.
Crear una conexión a través de un túnel SSH
Otra medida que puedes adoptar con la que no necesitas hacer absolutamente ningún cambio en tu sitio es encriptar las comunicaciones entre la red que te conectas y tu sitio. En este apartado debes considerar la utilización de una VPN o un túnel SSH, lo que tiene el efecto de cifrar los datos que otros usuarios de una misma red pueden ver (sólo se pueden “ver” los datos en plano entre el punto de salida del túnel y tu sitio).
Si tienes contratado algún servicio de hosting (de preferencia una VPS o algún servidor cloud), puedes utilizar tu mismo servidor para crear un túnel SSH y te ahorras la cuota mensual de un servicio externo. El proceso es bastante sencillo: desde tu terminal local, debes teclear lo siguiente:
ssh -v -NCD 9090 usuario@tuservidor.com
Donde 9090 es un puerto local donde se iniciará el túnel. Luego, debes activar las conexiones a través de proxy. Por ejemplo, en Firefox esto se hace en Preferencias → Avanzado → Red.
En Ubuntu, puedes activar el proxy para todas las conexiones a través de tus preferencias en Proxy de la red. Luego, especifica método “Manual” y en servidor socks ingresas la información de la conexión (localhost y 9090).
Cuando dejes de utilizar el túnel, debes recordar desactivar el proxy donde corresponda.
Acceder a la administración sobre SSL
Finalmente la mejor opción, aunque requiere un poco de trabajo en el mismo sitio, es habilitar el uso de la administración a través de una conexión segura sobre SSL, para lo cual vamos a necesitar un certificado SSL.
Por supuesto, una opción es comprar un certificado con una autoridad de certificación o a través de un intermediario, pero también podemos lograr el mismo efecto con un certificado autofirmado. Las diferencias entre un certificado “comprado” y uno autofirmado son básicamente dos:
- En un certificado autofirmado no se puede comprobar automáticamente que te estás comunicando con el sitio donde instalaste el certificado ya que no hay un tercero que valide la identidad del sitio con el certificado generado, por lo que existe la posibilidad de que puedas estar ante un ataque de man-in-the-middle, o sea, que envíes tus datos a otro servidor.
- Debido a lo anterior, con un certificado autofirmado el navegador te va a presentar una advertencia indicando que el certificado de seguridad del sitio no es de confianza, o algo así… probablemente con grandes letras rojas y signos de exclamación… lo suficientemente escandaloso como para provocar un pequeño ataque de pánico en usuarios poco técnicos.
En definitiva, un certificado autofirmado va a asegurar que los datos se transmitan de forma encriptada, pero no que el receptor es quien dice ser.
Por lo tanto, la opción de usar un certificado autofirmado, si bien válida y perfectamente segura para encriptar los datos, podría no ser la mejor si estás pensando en implementarla en algún sitio de un cliente.
Hay más información al respecto en Adding “https://” to Your Site for Free and Misconceptions About the Security of Self-Signed Certificates.
Generación del certificado autofirmado
Ok, manos a la obra: vamos a generar el certificado con Ubuntu y configurarlo en un servidor nginx.
Para lo primero, te sugiero loguearte momentáneamente como root (sudo su) y luego crear el directorio /root/ssl/sitio.com — obviamente puedes elegir otra ubicación donde guardar el certificado u otra estructura de carpetas, pero como sea es importante que tenga un orden. El comando para crear el certificado es:
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /root/ssl/sitio.com/server.key -out /root/ssl/sitio.com/server.crt
Con ese único comando vas a generar y firmar el certificado; te va a solicitar algunos datos pero el más importante es Common Name (e.g. server FQDN or YOUR name), ya que debe corresponder con la URL del sitio para el cual estás generando el certificado.
Configuración del certificado en NGINX
Idealmente tu configuración de virtual hosts está ordenada por dominios o sitios, ¿cierto? Excelente. Si es así, sólo te queda editar la configuración del virtual host que corresponde:
server { listen 80 default_server; listen [::]:80 default_server ipv6only=on; listen 443 ssl; root /var/www/sitio.com; index index.php index.html index.htm; server_name sitio.com; ssl_certificate /root/ssl/sitio.com/server.crt; ssl_certificate_key /root/ssl/sitio.com/server.key; location / { try_files index.php $uri $uri/ =404; } }
Puedes ver más detalles en How To Create a SSL Certificate on Nginx for Ubuntu 14.04.
Configurar tu sitio de WordPress
Llegamos a la configuración de WordPress. Acá tenemos básicamente dos opciones que son complementarias; se trata de definir dos constantes en el archivo wp-config.php que nos van a permitir lo siguiente:
// la información de login se envía sobre HTTPS define('FORCE_SSL_LOGIN', true); // TODA la administración de WordPress funcionará sobre HTTPS define('FORCE_SSL_ADMIN', true);
¿La diferencia entre ambas? Con la primera, solamente el envío de tu usuario y contraseña y la respuesta de WordPress están encriptadas (esto incluye la cookie de autenticación); todo el resto del sitio sigue funcionando sin HTTPS.
Puedes encontrar más información en Definitive Guide to WordPress SSL.
Finalmente, si utilizas el módulo de CDN de W3 Total Cache y estás utilizando toda la administración sobre SSL, probablemente vas a tener advertencias de contenido mixto, es decir el navegador te alerta que algunos de los archivos de la página actual no se han cargado sobre HTTPS. Para evitarlo, lo más sencillo es desactivar la CDN en la administración: ingresas a Performance → CDN y luego en la sección avanzado chequea la opción Disable CDN on SSL pages.
Ojo también si utilizas CloudFlare ya que en su versión gratis no tienen soporte para conexiones sobre HTTPS, por lo que vas a necesitar gestionar tus DNS con otro servicio.