Seguridad O.W.A.S.P. y WordPress

Cuando hablamos de aplicar medidas de seguridad en WordPress solemos remitirnos al estándar de Hardening WordPress, alojado en el Codex, pero a poco que investigues te das cuenta de que es una información demasiado escasa.

Si de verdad quieres aplicar protocolos de seguridad activa y pasiva a instalaciones WordPress hace falta algo más, en realidad muchísimo más, no digamos si tienes que educar a administradores de sistemas, desarrolladores, incluso usuarios y empleados.

Pero la buena noticia es que no hace falta inventarse procedimientos, protocolos, o manuales de prevención, detección y solución de problemas de seguridad para WordPress, ¡ya está inventado!

O.W.A.S.P.

Me refiero a O.W.A.S.P., acrónimo de Open Web Application Security Projecto Proyecto abierto de seguridad en aplicaciones web.

O.W.A.S.P. ofrece una lista de los principales riesgos de cualquier aplicación web, y WordPress lo es, y cómo solucionarlos, principalmente de manera proactiva, antes de tener que arreglar el desastre.

Es un estándar del mercado, al que no somos ajenos, y que podemos aplicar.

O.W.A.S.P. Top 10

Una de las utilidades más conocidas de O.W.A.S.P. es la lista Top 10 de los principales riesgos para aplicaciones web, que en su última versión son estos:

  1. A1 – Inyección
  2. A2 – Pérdida de autentificación
  3. A3 – Exposición de datos sensibles
  4. A4 – Entidades externas XML (XXE)
  5. A5 – Pérdida del control de acceso
  6. A6 – Configuración de seguridad incorrecta
  7. A7 – Cross Site Scripting (XSS)
  8. A8 – Deserialización segura
  9. A9 – Uso de componentes con vulnerabilidades conocidas
  10. A10 – Registro y monitoreo insuficientes

Cómo aplicar O.W.A.S.P. en WordPress

Un modo fantástico, muy práctico, de aplicar O.W.A.S.P. en WordPress es empezar por analizar la lista de los riesgos Top 10 y ver cómo protegernos de ellos con WordPress.

A1 – Inyección

Las inyecciones SQL suelen ser vulnerabilidades provocadas por sanear incorrectamente los inputs de programación. Con ellas el atacante puede acceder a la base de datos e inyectar información.

Muchas de las medidas del riesgo A1 se aplican a otros riesgos, así que es la base de todo.

Medidas a aplicar para evitar este riesgo son las siguientes:

  • Siempre versiones seguras de WordPress
  • Plugins seguros y bien programados (no versiones piratas)
  • Temas seguros y bien programados (no versiones piratas)
  • Buenas contraseñas, sí
  • Nada «por defecto» (usuario admin, prefijo wp_, /?author=1)
  • Moderación de comentarios, un método más común de lo que se piensa de inyectar código
  • Hosting de calidad, con medidas específicas de seguridad para wordpress
  • Hosting con versiones seguras de software y WAF
  • Permisos 400 en archivos sensibles (.htaccess, wp-config.php)
  • Mueve el archivo wp-config.php al directorio superior
  • Desactiva ejecución php

Una aplicación práctica es este código en .htaccess, además de evitar el listado de archivos, evitamos scripts y cadenas GLOBALS o _REQUEST que pretendan inyectar código:

Options -Indexes
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{QUERY_STRING} (<|%3C).*script.*(>|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} GLOBALS(=|[|%[0-9A-Z]{0,2}) [OR]
RewriteCond %{QUERY_STRING} _REQUEST(=|[|%[0-9A-Z]{0,2})
RewriteRule ^(.*)$ index.php [F,L]

Con este otro código en tu archivo .htaccess y un .htaccess adicional en uploads, content, wp-includes, y carpetas de caché de plugins y temas, evitas la ejecución de php directamente, aunque el archivo no termine en .php sino, por ejemplo .php.jpg:

<FilesMatch “\.(php|php\.)$”>
Order Allow,Deny
Deny from all
</FilesMatch>

También, para evitar el uso de author=1 puedes evitar la enumeración de usuarios añadiendo este código a tu functions.php:

if (!is_admin()) {
	if (preg_match('/author=([0-9]*)/i', $_SERVER['QUERY_STRING'])) die();
	add_filter('redirect_canonical', 'shapeSpace_check_enum', 10, 2);
}
function shapeSpace_check_enum($redirect, $request) {
	if (preg_match('/\?author=([0-9]*)(\/*)/i', $request)) die();
	else return $redirect;
}

A2 – Pérdida de autentificación

Cualquier fallo de programación o ausencia de medidas de contención puede hacer que se rompa o se pierda la autentificación de tu WordPress.

Para ello es fundamental que tengas en cuenta lo siguiente:

  • Siempre versiones seguras de TODO (NO VERSIONES PIRATAS)
  • Buenas contraseñas, sí, siempre
  • Nada «por defecto»
  • Define las secret_keys de wordpress en wp-config.php
  • No mostrar errores de login
  • Solo 2 administradores, no para tareas habituales
  • Doble verificación

Para aplicar inmediatamente, este código en nuestro functions.php evitamos que WP muestre los errores de acceso:

add_filter('login_errors',create_function('$a', "return null;"));

Como wp-config.php tiene mucha información sensible con este código en .htaccess evitamos que se acceda al mismo. Lo mismo para cualquier archivo que empiece con . o sea, cualquier archivo de sistema, como .htaccess:

<files wp-config.php>
order allow,deny
deny from all
</files>
<FilesMatch "^\.">
Order allow, deny
Deny from all
</FilesMatch>

A3 – Exposición de datos sensibles

¿Cuántos datos tienes que guardar de los usuarios? ¿durante cuánto tiempo? ¿para qué? Lo mismo tu hosting.

Especialmente importante es que sea PCI compliance, unos estándares de seguridad para transacciones online.

Unas medidas casi de sentido común:

  • ¿Te acuerdas del RGPD?
  • Hosting RGPD
  • Hosting pci compliance
  • Aplica todo lo visto en A1 y A2
  • Buena gestión de permisos de usuarios
  • Borrado programado de datos sensibles
  • SSL = HTTPS

A4 – Entidades externas XML (XXE)

Las entidades XXE se combaten con software bien programado, que no use parsers (analizadores de sintaxis externos)

Un ejemplo de cómo evitar parsers en PHP sería con este código:

libxml_disable_entity_loader(true);

Aquí, las medidas a aplicar serían las siguientes:

  • Software original y de calidad (a1)
  • Evita la carga de extensiones externas (DOM, XMLWRITER, XMLREADER)
  • Evita cualquier parser XML
  • Evita parsers en PHP

A5 – Pérdida del control de acceso

Este es un riesgo de seguridad que no suele suceder mucho, y del que no debes preocuparte si aseguras tu WordPress con las medidas expuestas en los puntos A1 y A2.

Por resumir, haz esto:

  • Aplica las medidas para A1 y A2
  • Controla las llamadas de las APIs (JSON REST API especialmente)
  • Ten siempre a mano backups
  • Desactiva XML-RPC

Puedes quitar del todo XML-RPC añadiendo este código al archivo .htaccess:

<Files xmlrpc.php>
  <IfModule mod_authz_core.c>
    Require all denied
  </IfModule>
  <IfModule !mod_authz_core.c>
    Order allow,deny
    Deny from all
  </IfModule>
</Files>

O con este otro código, bastante más radical, también en .htaccess (no uses los dos, solo uno):

RewriteCond %{REQUEST_METHOD} ^(GET|POST|PUT|PATCH|DELETE) [NC]
RewriteCond %{REQUEST_URI} ^.*wp-json/wp/ [NC]
RewriteRule ^(.*)$ - [F]

Y si tu servidor es NGINX el código a utilizar en su archivo de configuración es este otro:

location = /xmlrpc.php {
 deny all;
 }

A6 – Configuración de seguridad incorrecta

Aquí volvemos a los básicos que hemos visto. Principalmente aplica todo lo anterior relativo a la protección de usuarios y archivos, y exposición de datos.

Algunas medidas concretas:

  • No uses nada por defecto, tampoco en tu router, móvil, ordenador
  • No uses permisos de archivos y carpetas incorrectos (650 para archivos, 750 para carpetas, 400 para .htaccess y wp-config.php)
  • Recuerda A1 y A2

A7 – Cross Site Scripting (XSS)

Un ataque XSS, básicamente, explota vulnerabilidades conocidas así que actualiza todo y aplica las medidas de protección del riesgo A1.

O sea…

  • Es la vulnerabilidad más común y extendida, así que tómatelo en serio
  • Software actualizado y con garantías = A1
  • Desarrollador: valida, sanea y escapa todo …

Desarrollador: Valida todo

  • is_numeric()
  • preg_match()
  • filter_var()
  • in_array()

Desarrollador: Sanea todo

  • sanitize_email
  • sanitize_file_name
  • sanitize_html_class
  • sanitize_text_field
  • sanitize_textarea_field
  • esc_url_raw
  • sanitize_option 
  • sanitize_meta
  • wp_kses
  • sanitize_key
  • sanitize_user
  • sanitize_mime_type
  • sanitize_title
  • wp_filter_post_kses

Desarrollador: Escapa todo

  • esc_html 
  • esc_url
  • esc_js
  • esc_attr
  • esc_textarea

A8 – Deserialización segura

La deserialización, o decodificación, debe ser segura, pues permite la comunicación insegura de datos y objetos.

Recuerda:

  • Afecta a cachés, bases de datos, tokens de APIs, a todo wordpress
  • Evita el uso de objetos  serializados desde fuentes inseguras
  • Mantén todo actualizado
  • Aplica A1 a muerte

A9 – Uso de componentes con vulnerabilidades conocidas

Esto lo podría resumir en:

  • No te alojes en hosting inseguros
  • No uses software con vulnerabilidades conocidas

Para estar al día de vulnerabilidades tienes estas webs, entre otras:

A10 – Registro y monitoreo insuficientes

Debes buscar de manera proactiva cualquier posible código vulnerable y exposiciones de información tanto en el código como en el sistema.

Por ejemplo…

  • Busca código ofuscado
  • Busca código base64
  • Busca llamadas al sistema (exec, passthru, system, shell_exec, etc.)
  • Busca ejecuciones de código PHP (eval, assert, preg_replace, etc.)
  • Busca exposiciones de información (phpinfo, getenv, getmygid/pid/uid, etc.)
  • Busca funciones del sistema de archivos (fopen, bz/gzopen, chgrp/own/mod, etc.)
  • ¿Te acuerdas del RGPD?: Este plugin te ayudará a vigilar la actividad: https://es.wordpress.org/plugins/wp-security-audit-log/

Hoja de ruta para desarrolladores

Si eres desarrollador, O.W.A.S.P. ofrece varios documentos, plantillas, de todo, una fantástica hoja de ruta de seguridad web, basada en estos pilares que todo desarrollador o responsable de un sistema web debe aplicar.

  • DEFINIR SEGURIDAD Y REQUISITOS DE SEGURIDAD: Para ofrecer aplicaciones web seguras es fundamental definir qué es seguro y qué no en tu sistema (o todos). Para eso OWASP ofrece el ASVS, un estándar de verificación de seguridad de aplicaciones, en su wiki
  • SEGURIDAD POR DISEÑO: Siempre es mejor, más seguro, incluso rentable, diseñar la seguridad desde el principio, y no tener luego que ir asegurando cada aplicación y API. Hay una hoja de seguimiento master que puedes usar como modelo.
  • CONTROLES ESTÁNDAR DE SEGURIDAD: Para establecer controles en cada framework, como WordPress, para verificaciones de seguridad en cada punto del sistema. Lo mejor son los controles proactivos, y OWASP ofrece una lista de 10 importantes:
    • Definir los requisitos de seguridad
    • Equilibrar la seguridad de frameworks y bibliotecas utilizadas
    • Asegurar el acceso a bases de datos
    • Validar todos los inputs
    • Implementar el control de la identidad digital
    • Reforzar los controles de acceso
    • Proteger los datos en todas partes
    • Implementar seguridad y monitorización en el acceso
    • Gestionar cualquier error o excepción

Como ves están alineados con las riesgos críticos de la lista OWASP Top 10.

  • CICLO DE VIDA DE DESARROLLO SEGURO: Hay que adaptar los modelos de seguridad a cada negocio y sus riesgos. Para  ello nos podemos ayudar de SAMM, un modelo de garantía de la madurez de sistemas de seguridad, que podemos aplicar y usar en nuestro negocio.
  • EDUCAR EN SEGURIDAD: Hay que educar a desarrolladores, testers y usuarios en los requisitos de seguridad de cada aplicación y API, a todos los niveles.

Resumiendo

O.W.A.S.P. ofrece al propietario, administrador y desarrollador WordPress un modelo estandarizado y preciso, hasta el más mínimo detalle, de seguridad preventiva y activa para aplicar desde un blog personal hasta redes de sitios profesionales.

Si tuviese que resumir todo lo que nos enseña O.W.A.S.P. en pocas palabras vendría a ser algo así:

  1. Seguridad preventiva
  2. Hosting de confianza
  3. Software de confianza
  4. Permisos adecuados
  5. Monitoreo constante

Lo importante es que con O.W.A.S.P. disponemos de un estándar de seguridad web, con instrucciones, manuales, guías y hojas de ruta detalladas para aplicar a WordPress y hacer más segura cualquier instalación.


Este artículo es una versión adaptada y ampliada de mi ponencia en WordCamp Pontevedra 2018, que puedes ver y descargar en este enlace

VALORA Y COMPARTE ESTE ARTÍCULO PARA MEJORAR LA CALIDAD DEL BLOG…
(13 votos, promedio: 4.7)

¿Te gustó este artículo? ¡Ni te imaginas lo que te estás perdiendo en YouTube!

14 comentarios en “Seguridad O.W.A.S.P. y WordPress”

  1. Todo muy bien explicado, una guía de ayuda para el desarrollador de una instalación de WordPress.
    Estaré al día de todas las novedades de OWASP
    Gracias por compartir!!!!

  2. Gracias por la información, pero hay un problema que no he podido solucionar. Google Analytics me muestra muchos intentos de acceso a una carpeta y archico que no existe (html):

    /h/6728598.html

    Cada tanto cambian los números, y a pesar que tengo un plugin de protección que banea IPS con demasiados intentos a archivos existentes, no surte efecto, supongo que por ser .html

    Alguna idea de que puedo hacer? No sé si soy al único que le ha pasado esto. Adicionalmente, aumenta mucho el valor de la tasa de rebote.

  3. Una guía de primera!! He probado a aplicar la resticción de los archivos de sistema que empiecen por punto y me ha generado un error 500. He dejado la protección para WP-config que ya la tenía de otro artículo 🙂
    Gracias!!

  4. Hace tiempo que sigo tus post, Fernando. Qué buenos son todos y qué ayuda tan importante brindas…
    Si no existieras, habría que inventarte!!!
    Gracias!! 🙂

  5. Robinson Giraldo Taborda

    que se supone que se hace con A7 eso donde se pega que se hace donde activa o que lo que es pa que

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

 

Ir arriba Ir al contenido