Seguridad WordPress: 15 Pasos para Blindar tu Sitio en 2025
WordPress alimenta el 43 % de todos los sitios web del mundo, lo que lo convierte en el objetivo número uno de ataques automatizados. Esta guía técnica cubre las medidas de seguridad que debes implementar en las primeras 24 horas tras instalar WordPress en producción.
Hardening inmediato post-instalación
El primer paso es cambiar el prefijo de tablas de la BD, que por defecto es wp_. Cualquier script de SQL injection automatizado apunta a ese prefijo. También debes mover el archivo de configuración fuera del webroot:
# Mover wp-config.php un nivel arriba del webroot (WordPress lo busca ahí automáticamente)
mv ~/public_html/wp-config.php ~/wp-config.php
# Establecer permisos correctos (crítico)
chmod 600 ~/wp-config.php
find ~/public_html -type f -name "*.php" -exec chmod 644 {} \;
find ~/public_html -type d -exec chmod 755 {} \;
chmod 600 ~/public_html/.htaccess
# Deshabilitar la edición de archivos desde el panel admin de WP
echo "define('DISALLOW_FILE_EDIT', true);" >> ~/wp-config.php
# Deshabilitar ejecución de PHP en directorios de uploads
cat > ~/public_html/wp-content/uploads/.htaccess << 'EOF'
Require all denied
EOF
Proteger wp-admin y wp-login.php con .htaccess
Los ataques de fuerza bruta contra wp-login.php son el vector de ataque más común. Limitar el acceso por IP o añadir autenticación básica es la primera línea de defensa:
# Agregar al .htaccess en /public_html/wp-admin/
# Opción 1: Limitar acceso por IP (reemplaza con tus IPs)
<Files "*.php">
Require ip 187.188.0.0/16
Require ip 200.68.0.0/16
</Files>
# Opción 2: Autenticación HTTP básica sobre wp-login.php
# (agregar en /public_html/.htaccess)
<Files wp-login.php>
AuthType Basic
AuthName "Acceso Restringido"
AuthUserFile /home/usuario/.htpasswd
Require valid-user
</Files>
# Bloquear acceso directo a xmlrpc.php (usado en ataques DDoS amplificados)
<Files xmlrpc.php>
Require all denied
</Files>
# Generar el archivo .htpasswd
htpasswd -c ~/.htpasswd adminwp
# Te pedirá la contraseña dos veces
Configuración de wp-config.php con llaves de seguridad y salts
<?php
// Generar llaves únicas en: https://api.wordpress.org/secret-key/1.1/salt/
define('AUTH_KEY', 'tu-clave-unica-aqui-40-chars-minimo');
define('SECURE_AUTH_KEY', 'otra-clave-diferente-aqui');
define('LOGGED_IN_KEY', 'y-otra-mas-diferente');
define('NONCE_KEY', 'y-otra-mas');
define('AUTH_SALT', 'salt-unico-1');
define('SECURE_AUTH_SALT', 'salt-unico-2');
define('LOGGED_IN_SALT', 'salt-unico-3');
define('NONCE_SALT', 'salt-unico-4');
// Forzar SSL en área de admin
define('FORCE_SSL_ADMIN', true);
// Limitar revisiones de posts (evita que la BD crezca descontroladamente)
define('WP_POST_REVISIONS', 5);
// Desactivar el editor de plugins/temas desde admin
define('DISALLOW_FILE_EDIT', true);
define('DISALLOW_FILE_MODS', true); // También bloquea actualizaciones desde admin
// Mover directorio de uploads fuera del webroot (avanzado)
// define('UPLOADS', '../private_uploads'); // Requiere configuración adicional
Auditoría de plugins y temas: vectores de ataque más comunes
El 90 % de los hackeos de WordPress ocurren a través de plugins y temas vulnerables, no a través del core. Usa WP-CLI para auditar:
# Listar todos los plugins con su versión y estado
wp plugin list --path=/home/usuario/public_html --allow-root
# Verificar integridad del core de WordPress (compara checksums)
wp core verify-checksums --path=/home/usuario/public_html --allow-root
# Verificar integridad de plugins
wp plugin verify-checksums --all --path=/home/usuario/public_html --allow-root
# Ver plugins sin actualizar (posibles vulnerabilidades)
wp plugin list --update=available --path=/home/usuario/public_html --allow-root --format=table --fields=name,version,update_version
# Actualizar todos los plugins en un solo comando
wp plugin update --all --path=/home/usuario/public_html --allow-root
# Eliminar plugins y temas inactivos (superficie de ataque innecesaria)
wp plugin delete hello akismet --path=/home/usuario/public_html --allow-root
wp theme delete twentytwenty twentytwentyone --path=/home/usuario/public_html --allow-root
base64_decode(eval()) para ocultar código malicioso. Si usas temas de fuentes no oficiales, estás comprometiendo tu servidor completo.
Detección de malware con Imunify360 y WP-CLI
# Escanear con Imunify360 desde línea de comandos
imunify360-agent malware-scan --path=/home/usuario/public_html
# Ver resultados del último escaneo
imunify360-agent infected-domains list
# Buscar archivos PHP modificados en las últimas 24 horas (señal de hackeo)
find ~/public_html -name "*.php" -newer ~/public_html/wp-config.php -mtime -1 -not -path "*/cache/*" -ls | sort -k8,9
# Buscar patrones de malware comunes manualmente
grep -r --include="*.php" -l "base64_decode\|eval(gzin\|str_rot13\|preg_replace.*\/e" ~/public_html/ 2>/dev/null | grep -v "vendor/"
# Buscar archivos con nombres sospechosos
find ~/public_html -name "*.php" | grep -E "(shell|c99|r57|hack|backdoor|webshell)"
Configurar actualizaciones automáticas del core
// En wp-config.php: habilitar actualizaciones automáticas de seguridad
define('WP_AUTO_UPDATE_CORE', 'minor'); // Solo actualizaciones de seguridad (e.g., 6.4.1 → 6.4.2)
// define('WP_AUTO_UPDATE_CORE', true); // Actualizaciones mayores también (más riesgo)
# Configurar wp-cron real (más confiable que el cron de PHP)
# Desactivar wp-cron en wp-config.php:
# define('DISABLE_WP_CRON', true);
# Agregar en crontab del servidor:
crontab -e
# Agregar línea:
# */15 * * * * wget -q -O - https://tudominio.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1
| Amenaza | Vector de ataque | Mitigación |
|---|---|---|
| Brute force admin | wp-login.php | Limitar por IP + 2FA + Fail2ban |
| Plugin vulnerable | CVE en plugin desactualizado | Actualizaciones automáticas + WPScan |
| SQL Injection | Formularios sin sanitizar | WAF Imunify360 + tablas con prefijo único |
| File upload | wp-content/uploads | .htaccess denegando PHP en uploads |
| XSS | Comentarios/formularios | CSP headers + sanitización WP |
| Backdoor nulled | Tema/plugin pirata | Solo repositorio oficial + verificación checksum |
Escenarios Prácticos: Seguridad WordPress en Producción
Escenario 1 — Tienda WooCommerce que sufrió un hackeo de redirección: El sitio redirigía a farmacia falsa. Proceso de limpieza y hardening post-hackeo:
# 1. Identificar archivos modificados recientemente
find /home/usuario/public_html -name "*.php" -newer /tmp/reference_file -not -path "*/cache/*" | head -30
# 2. Buscar código malicioso común (base64 encoded)
grep -r "base64_decode" /home/usuario/public_html --include="*.php" -l
# 3. Buscar eval con variables (patrón común de backdoor)
grep -r "eval(\$" /home/usuario/public_html --include="*.php" -l
# 4. Verificar integridad de archivos core de WordPress
wp core verify-checksums --allow-root
# Reinstalar core si hay modificaciones:
wp core download --force --allow-root
# 5. Cambiar TODAS las credenciales tras limpiar
wp user update 1 --user_pass="NuevaPassword123!@#" --allow-root
# Rotar salts y keys en wp-config.php
wp config shuffle-salts --allow-root
Escenario 2 — Blog nuevo implementando hardening preventivo: Configuración de seguridad desde el primer día: 2FA, contraseñas fuertes, límite de intentos de login, y archivo wp-config.php fuera del webroot.
Errores Comunes de Seguridad en WordPress
| Vulnerabilidad | Riesgo | Causa | Solución |
|---|---|---|---|
| Contraseña admin débil | Acceso total al sitio | Password fácil de adivinar | Mínimo 16 caracteres, usar gestor de contraseñas |
| Plugins desactualizados | Explotación de CVE conocidos | No actualizar regularmente | Activar actualizaciones automáticas de seguridad |
| Admin user = "admin" | Fuerza bruta más efectiva | Nombre de usuario predecible | Crear usuario con nombre único, eliminar "admin" |
| xmlrpc.php expuesto | DDoS y ataques de fuerza bruta | Habilitado por defecto | Deshabilitar si no usas apps móviles WP |
| Sin 2FA en wp-admin | Acceso con solo contraseña comprometida | Seguridad de una sola capa | Instalar WP 2FA o Google Authenticator para WP |
Preguntas Frecuentes sobre Seguridad WordPress
¿Cada cuánto debo hacer auditorías de seguridad en WordPress?
Mínimo mensual: revisar usuarios con roles de administrador, plugins activos y sus versiones, y logs de acceso buscando IPs sospechosas. Trimestral: escáner completo de malware con Wordfence o Imunify360, y revisión de permisos de archivos. Anual: auditoría completa de seguridad con prueba de penetración si el sitio maneja datos sensibles o pagos.
¿Wordfence o Sucuri para proteger WordPress?
Wordfence Free: firewall y escáner de malware, excelente para la mayoría de sitios. Bloquea IPs maliciosas automáticamente. Sucuri: firewall a nivel de DNS (más efectivo contra DDoS) y CDN incluido. Sucuri es más caro pero protege antes de que el tráfico llegue a tu servidor. Para sitios con alto tráfico y riesgo de DDoS: Sucuri. Para sitios normales: Wordfence Free es suficiente.
¿Cómo protejo wp-admin sin perder acceso?
Tres capas de protección: 1) Cambia la URL de login con WPS Hide Login plugin (de /wp-admin a /ingresar-empresa). 2) Limita acceso a wp-admin por IP con .htaccess si tu IP es estática. 3) Activa 2FA. Para IPs dinámicas, usa la restricción por geolocalización (solo México) si todos tus admins están en México.
¿Qué permisos de archivo debo tener en WordPress?
Directorios: 755 (rwxr-xr-x). Archivos PHP: 644 (rw-r--r--). wp-config.php: 600
o 640 (solo el propietario puede leer/escribir). La carpeta uploads: 755, nunca 777.
Si un archivo o directorio tiene permisos 777 (escritura para todos), es una
vulnerabilidad crítica. Verifica con: find . -perm 777 -type f desde el
directorio raíz de WordPress.
¿Qué información registra WordPress que debo monitorear?
WordPress no tiene sistema de logs nativo robusto. Instala WP Activity Log para registrar: intentos de login (fallidos y exitosos), cambios en plugins/temas, modificaciones de usuarios y cambios en configuración. Estos logs te permiten detectar acceso no autorizado y reconstruir qué pasó durante un incidente de seguridad. Almacena logs fuera del servidor de WordPress para que el atacante no pueda borrarlos.
📚 Profundiza en estos temas
- Imunify360: WAF, escaneo de malware y Proactive Defense en acción
- SSL/HTTPS: por qué es obligatorio y cómo instalarlo gratis con Let's Encrypt
- Instalar WordPress desde cero en cPanel con configuración segura
- Plugins esenciales de WordPress 2025: cuáles instalar y cuáles evitar
- Protección DDoS: cómo defender tu servidor de ataques volumétricos
Fundador de VacaWeb con más de 15 años administrando infraestructura Linux en producción. Especialista en LiteSpeed, CloudLinux, cPanel/WHM y arquitectura de hosting de alto rendimiento para el mercado mexicano. Ha diseñado y migrado la infraestructura de más de 1,200 sitios web empresariales.