Proteger wp-config.php: 10 ajustes que debe revisar
Cómo proteger wp-config.php en 10 revisiones: salts únicos, depuración en producción, FORCE_SSL_ADMIN, permisos, copias olvidadas y edición segura del archivo.
También en: English Deutsch Français Italiano Polski Português Türkçe
wp-config.php contiene la contraseña de su base de datos, las claves que firman cada cookie de inicio de sesión y los ajustes que deciden si los errores se muestran a los visitantes. La mayoría de los propietarios de sitios web nunca lo han abierto. Esta guía para proteger wp-config.php es una auditoría de diez puntos de ese único archivo. Para cada revisión encontrará la línea exacta, el valor de producción, cómo comprobarlo y qué riesgos no cubre el ajuste.
Qué controla wp-config.php y cómo editarlo sin provocar una pantalla en blanco
El archivo contiene tres tipos de cosas. Primero, las credenciales de la base de datos. Segundo, ocho claves de seguridad y salts. Tercero, constantes que modifican el comportamiento de WordPress. Quien pueda leer el archivo puede entrar en su base de datos. Quien pueda escribir en él puede ejecutar código en cada carga de página.
Es además el archivo más fácil de romper. Un solo punto y coma olvidado produce una pantalla en blanco o un error fatal para todos los visitantes. Siga este procedimiento cada vez:
- Descargue a su ordenador una copia del archivo actual.
- Edite por SFTP o SSH, no con un gestor de archivos en el navegador ni con un plugin.
- Si tiene acceso a la shell, ejecute
php -l wp-config.php. Debe responder "No syntax errors detected". - Recargue el front end y
/wp-admin/en una ventana privada. - Si algo falla, suba de nuevo su copia. Después corrija el cambio con calma.
- Si todo funciona, elimine las copias temporales que haya creado en el servidor (como
wp-config.php.bak). Conserve la copia en su ordenador.
La ubicación importa. Cerca del final del archivo encontrará el comentario /* That's all, stop editing! Happy publishing. */, seguido de require_once ABSPATH . 'wp-settings.php';. Las constantes definidas después de esa línea llegan demasiado tarde para la mayoría de los ajustes. Coloque cada nuevo define() por encima del comentario. La referencia oficial es la página de wp-config.php en la documentación para desarrolladores de WordPress.
Secretos: credenciales de la base de datos y claves de seguridad y salts únicos
Revisión 1: credenciales de la base de datos. DB_USER debe ser un usuario de base de datos que exista solo para este sitio, con una contraseña larga y aleatoria. Si tres sitios comparten un mismo usuario, la filtración de uno expone los tres. No reutilice nunca aquí la contraseña del panel de hosting o de control. Esta revisión no sirve de nada si el atacante ya ejecuta código en el servidor, porque entonces puede leer el archivo igualmente.
Revisión 2: claves y salts. Son ocho: AUTH_KEY, SECURE_AUTH_KEY, LOGGED_IN_KEY, NONCE_KEY y las cuatro constantes _SALT correspondientes. Deben ser largas, aleatorias y exclusivas de este sitio. Si alguna todavía dice put your unique phrase here, corríjala hoy mismo. Puede generar un conjunto nuevo en api.wordpress.org/secret-key/1.1/salt/ y pegarlo sobre el bloque anterior. Con WP-CLI basta un comando:
wp config shuffle-salts
Cambie los salts después de un ataque, cuando se marche un administrador o una agencia con acceso a los archivos, o si el archivo llegó a quedar expuesto.
Tras una intrusión, renovar estos secretos es solo un paso de una limpieza más amplia. Consulte cómo eliminar malware de WordPress para ver el orden completo.
Ajustes de depuración en producción: WP_DEBUG, WP_DEBUG_DISPLAY y WP_DEBUG_LOG
Revisión 3: WP_DEBUG. En un sitio en producción debe valer false. Los errores mostrados revelan rutas del servidor, nombres de plugins y, a veces, fragmentos de consultas. Un atacante puede aprovecharlo para elegir su objetivo.
define( 'WP_DEBUG', false );
Poner WP_DEBUG en false no desactiva el ajuste display_errors del propio PHP. Si su proveedor lo tiene activado, los avisos pueden seguir apareciendo en la página. Pregunte al proveedor o revise la configuración de PHP si administra su propio servidor.
Revisión 4: si necesita registros, ocúltelos y muévalos. A veces hay que depurar en producción. En ese caso, no muestre nunca los errores en la página ni use la ubicación predeterminada del registro. WP_DEBUG_LOG con valor true escribe en wp-content/debug.log, que a menudo se puede descargar públicamente. Indique en su lugar una ruta de archivo fuera de la raíz web:
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_DISPLAY', false );
define( 'WP_DEBUG_LOG', '/home/example/logs/wp-debug.log' );
@ini_set( 'display_errors', '0' );
El directorio debe existir y el usuario de PHP debe poder escribir en él. Después compruebe que no queda ningún registro antiguo accesible públicamente:
curl -I https://example.com/wp-content/debug.log
Lo que busca es un 403 o un 404. Un 200 significa que cualquiera puede leer el registro. Elimínelo.
Los registros suelen contener direcciones de correo electrónico, direcciones IP y datos de formularios, es decir, datos personales. Desactive el registro cuando termine y elimine o rote los archivos antiguos. Los detalles de cada constante están en la documentación de depuración de WordPress.
HTTPS y entorno: FORCE_SSL_ADMIN y WP_ENVIRONMENT_TYPE
Revisión 5: FORCE_SSL_ADMIN. Mantiene la página de acceso, el escritorio y las cookies de administración sobre HTTPS:
define( 'FORCE_SSL_ADMIN', true );
Solo cubre el área de administración y los inicios de sesión. No sustituye a una redirección de HTTP a HTTPS en todo el sitio configurada en el servidor, ni es HSTS.
Revisión 6: WP_ENVIRONMENT_TYPE. Este ajuste indica a WordPress y a los plugins en qué tipo de sitio se están ejecutando. Los valores válidos son production, staging, development y local. El valor predeterminado es production.
define( 'WP_ENVIRONMENT_TYPE', 'production' );
El ajuste tiene efectos reales. En el núcleo, un entorno development activa WP_DEBUG cuando usted no lo ha definido. Algunos plugins y proveedores leen el valor para bloquear el correo saliente o cambiar la caché en sitios que no son de producción. Lo más importante, sin embargo, es etiquetar bien. Una copia de preproducción suele contener una réplica completa de los datos reales de clientes y pedidos. Márquela como staging y protéjala con autenticación HTTP o una restricción por IP. Elimínela cuando acabe el proyecto. Un subdominio de preproducción olvidado con la base de datos de clientes del año pasado es una fuente habitual de filtraciones.
Editor de archivos y modificaciones de archivos: DISALLOW_FILE_EDIT y DISALLOW_FILE_MODS
Revisión 7: añada esta línea a todos los sitios:
define( 'DISALLOW_FILE_EDIT', true );
Elimina del escritorio los editores de archivos de temas y plugins. Así, un acceso de administrador robado no se puede convertir en código en ejecución con unos pocos clics. No detiene a un atacante que pueda subir un plugin.
Revisión 8: DISALLOW_FILE_MODS va más lejos. Bloquea también la instalación y actualización de plugins y temas desde el escritorio y desactiva las actualizaciones automáticas en segundo plano. Actívelo solo cuando disponga de otra vía de actualización, como WP-CLI, un flujo de despliegue o actualizaciones gestionadas por el proveedor. De lo contrario, habrá congelado el sitio en las versiones vulnerables de hoy. Ambos ajustes y el flujo de actualización se tratan en DISALLOW_FILE_EDIT: desactivar el editor de archivos de WordPress.
Permisos, ubicación y copias olvidadas de wp-config.php
Revisión 9: permisos. El valor correcto depende del usuario con el que se ejecute PHP:
- 400 o 440: úselo cuando el propietario del archivo es un usuario distinto del de PHP. El grupo debe incluir al usuario de PHP, que solo necesita acceso de lectura.
- 600: úselo cuando PHP se ejecuta como propietario del archivo, algo habitual con pools de PHP-FPM por cuenta.
Evite 644 en hosting compartido, porque otras cuentas del mismo servidor podrían leerlo. No use nunca 777.
ls -l wp-config.php
chmod 440 wp-config.php
Para la propiedad y los permisos en el resto de la instalación, consulte web shells y permisos de archivos.
Mover el archivo un directorio por encima de la raíz web está permitido. WordPress lo busca allí automáticamente cuando la carpeta superior no contiene una instalación propia de WordPress. El beneficio es pequeño: solo importa si PHP deja de ejecutarse y el servidor entrega los archivos .php como texto plano. Hágalo si le resulta fácil, pero no lo cuente como una solución.
Revisión 10: copias olvidadas. Este es el riesgo mayor y más frecuente. Archivos como wp-config.php.bak, wp-config.php.old, wp-config.php.save, wp-config.php~ o un archivo temporal de editor como .wp-config.php.swp no terminan en .php. El servidor web puede servirlos como texto plano, con la contraseña de la base de datos incluida. Búsquelos:
find /var/www/example -name '*wp-config*' -type f
Solo deben quedar wp-config.php y el inofensivo wp-config-sample.php. Elimine el resto. Renombrarlos no sirve. Si una copia fue accesible por web, cambie también la contraseña de la base de datos y los salts.
Las 10 revisiones de wp-config.php en una tabla
| # | Ajuste | Valor en producción | Cómo comprobarlo |
|---|---|---|---|
| 1 | Credenciales de BD | Usuario propio, contraseña fuerte | Compare DB_USER entre sitios |
| 2 | Claves y salts | Únicos, aleatorios | grep -c "put your unique phrase" wp-config.php devuelve 0 |
| 3 | WP_DEBUG | false | wp config get WP_DEBUG |
| 4 | Pantalla/registro de depuración | Pantalla desactivada, registro fuera de la raíz web | curl -I .../debug.log da 403/404 |
| 5 | FORCE_SSL_ADMIN | true | wp config get FORCE_SSL_ADMIN |
| 6 | WP_ENVIRONMENT_TYPE | production | wp config get WP_ENVIRONMENT_TYPE |
| 7 | DISALLOW_FILE_EDIT | true | wp config has DISALLOW_FILE_EDIT |
| 8 | DISALLOW_FILE_MODS | Solo con vía de actualización | wp config has DISALLOW_FILE_MODS |
| 9 | Permisos | 400, 440 o 600 | ls -l wp-config.php |
| 10 | Copias olvidadas | Ninguna | Comando find anterior |
Un resultado limpio aquí no dice nada sobre plugins vulnerables, contraseñas de administrador débiles o una versión obsoleta de PHP. Para eso, use la lista de comprobación de seguridad de WordPress.
El plugin Security Audit & Compliance de secaudit.eu incluye un análisis de configuración y hardening y detecta secretos y archivos expuestos, como copias de seguridad olvidadas. También ofrece un interruptor opcional para desactivar los editores de archivos del escritorio → secaudit.eu
Su siguiente paso: descargue ahora una copia de wp-config.php y ejecute el comando find para localizar copias olvidadas. Lleva dos minutos y cubre la exposición que más se pasa por alto.
Preguntas frecuentes
¿Romperá mi sitio el cambio de salts?
No. Los contenidos, los ajustes y las contraseñas siguen como están. Todos los usuarios con sesión iniciada se desconectan y tienen que volver a identificarse, así que avise antes a sus editores y a los clientes de la tienda.
¿Debo cambiar el prefijo de las tablas en un sitio existente?
Normalmente no. Un prefijo personalizado aporta poca protección real, y cambiarlo en un sitio en producción implica renombrar tablas y actualizar entradas en las tablas options y usermeta. Un error puede dejar fuera a todos los usuarios. Déjelo como está, salvo que vaya a reconstruir el sitio de todos modos.
¿Puede un plugin gestionar wp-config.php por mí?
Algunos pueden. Sin embargo, un plugin con permiso de escritura sobre wp-config.php es en sí mismo un riesgo, porque una vulnerabilidad suya se convierte en acceso de escritura a su archivo más sensible. Es preferible editar manualmente por SFTP o SSH y guardar una copia de la última versión que funcionaba.
Compruebe su propio sitio
Security Audit & Compliance es el plugin de WordPress de secaudit.eu: busca malware, spam oculto, archivos del núcleo modificados y código vulnerable, y relaciona sus hallazgos con el art. 32 del RGPD, el art. 21 de NIS2 y el OWASP Top 10.
Ver qué comprueba el plugin