Guía de solución

Cómo bloquear readme.html y license.txt en WordPress

1 de mayo de 2026 Actualizado el 1 may 2026

Abre cualquier sitio de WordPress del mundo y añade /readme.html a la URL. En la inmensa mayoría de los casos obtendrás una página HTML limpia que anuncia con orgullo la versión exacta de WordPress en el titular. Lo mismo ocurre con /license.txt, que es algo menos específico, pero aun así confirma que el sitio funciona con WordPress y da una idea aproximada de cuán reciente es la instalación.

Ambos archivos vienen con el núcleo de WordPress. Se restauran en cada actualización. Ninguno de ellos es necesario para que el sitio funcione. El único público al que sirven realmente son los escáneres automatizados que identifican sitios por la versión del núcleo para cruzar el resultado con una lista de vulnerabilidades conocidas. Esta guía explica por qué eso importa en la práctica y cómo bloquear los archivos limpiamente en Apache, en nginx y en hosting compartido, donde tienes menos control directo.

¿Por qué importa que readme.html sea accesible?

La respuesta honesta es: por sí solo, no demasiado. Conocer la versión de WordPress de un sitio no es una vulnerabilidad. La versión del núcleo de WordPress no es un secreto y un atacante decidido suele poder averiguarla de todos modos, por ejemplo a partir de las metaetiquetas generator, del parámetro de versión en las consultas de scripts y estilos encolados, o de la estructura de la respuesta de la REST API.

Lo que cambia el panorama es la forma en que la explotación funciona hoy a gran escala. Los escáneres masivos no eligen un objetivo y luego buscan errores. Eligen un CVE, construyen una lista de todos los dominios de internet que ejecutan una versión afectada y lanzan el exploit contra toda la lista. La forma más barata de construir esa lista es solicitar readme.html en millones de dominios en paralelo y extraer la versión del titular. Cualquier cosa que haga que tu sitio sea invisible para ese paso de filtrado te saca de la lista de candidatos antes de que el exploit real llegue a ejecutarse.

Así que eliminar readme.html no hace que el sitio sea seguro. Elimina una de las huellas más baratas, lo que en la práctica significa que dejas de aparecer en listas automatizadas de "sitios WordPress que ejecutan la versión X.Y.Z". Eso compensa unos minutos de trabajo, aunque no sea el endurecimiento de seguridad más crítico que puedas hacer.

¿Y license.txt y los demás archivos del núcleo?

Misma familia de archivos, algo menos interesantes:

  • license.txt contiene el texto de la licencia GPL. No incluye un número de versión, pero su existencia en la raíz de WordPress es una señal clara de que el sitio funciona con WordPress.
  • wp-config-sample.php viene con cada instalación. No contiene credenciales, pero revela que nadie ha hecho limpieza tras la instalación.
  • readme.html es el que tiene el problema de divulgación de versión.

La regla de bloqueo de abajo cubre los tres de una sola vez. No hay ninguna buena razón para dejar ninguno de ellos accesible públicamente.

Opción 1: bloquear mediante .htaccess (Apache y LiteSpeed)

Si tu hosting usa Apache o LiteSpeed (lo que cubre a la mayoría de los hosters compartidos del mercado de habla alemana: All Inkl, IONOS, Strato, DomainFactory, Hostinger y la mayoría de los revendedores), puedes añadir el siguiente bloque al archivo .htaccess en el directorio raíz de tu WordPress:

<FilesMatch "^(readme\.html|license\.txt|wp-config-sample\.php)$">
  Require all denied
</FilesMatch>

El fragmento utiliza la sintaxis de Apache 2.4, que es la que llevan ejecutando todos los hosts desde hace años. Si te quedaste atascado en Apache 2.2 (extremadamente raro en 2026, pero posible en hosting heredado), usa la sintaxis antigua:

<FilesMatch "^(readme\.html|license\.txt|wp-config-sample\.php)$">
  Order allow,deny
  Deny from all
</FilesMatch>

Coloca el bloque por encima del marcador # BEGIN WordPress. Todo lo que está entre # BEGIN WordPress y # END WordPress lo gestiona el propio WordPress y se reescribe cuando cambian los enlaces permanentes o se ejecutan actualizaciones del núcleo. Lo que esté fuera de esos marcadores no se toca.

Tras guardar el archivo, abre https://tudominio.com/readme.html en una ventana privada del navegador. Deberías obtener un 403 Forbidden. Lo mismo para /license.txt. Si sigues viendo el contenido del archivo, tu hosting o bien ignora .htaccess por completo (raro en Apache, normal en nginx) o tiene AllowOverride configurado con un valor que descarta las directivas FilesMatch. Pasa a la Opción 3.

Opción 2: bloquear mediante nginx

En nginx no hay .htaccess. Si gestionas tu propio servidor (un VPS en Hetzner, Netcup, DigitalOcean, o un host nginx gestionado en el que controlas la configuración), añade lo siguiente dentro del bloque server de tu sitio:

location ~* ^/(readme\.html|license\.txt|wp-config-sample\.php)$ {
  deny all;
  return 403;
}

Recarga nginx con sudo nginx -t && sudo systemctl reload nginx y luego prueba con curl -I https://tudominio.com/readme.html. La primera línea de la respuesta debería ser HTTP/2 403.

Varios hosts gestionados de WordPress que utilizan nginx internamente (Raidboxes, Kinsta, WP Engine, Cloudways) incluyen reglas de este tipo por defecto. Vale la pena revisar la documentación del proveedor. Si no las tienen, el soporte normalmente añadirá la regla por ti si lo solicitas.

Opción 3: hosting compartido donde las sobrescrituras de .htaccess no se aplican

Algunos hosts compartidos restringidos ejecutan nginx e ignoran .htaccess por completo. Otros usan Apache pero con reglas AllowOverride restrictivas. Si ni la Opción 1 ni la Opción 2 están disponibles, tienes tres alternativas razonables, ordenadas por su durabilidad:

  1. Usa un plugin de seguridad que se encargue por ti del endurecimiento de archivos del núcleo. Tanto Solid Security como All In One WP Security & Firewall tienen una opción para "eliminar archivos del núcleo" u "ocultar la versión de WordPress" que se encarga de readme.html. Wordfence en modo de Protección Extendida también puede bloquear los archivos en la capa del WAF. La ventaja es que estos ajustes sobreviven automáticamente a las actualizaciones de WordPress.
  2. Vacía el archivo mediante un Must Use plugin. Si una regla a nivel de servidor es imposible, el enfoque más fiable es un pequeño mu plugin que sobrescribe readme.html y license.txt con contenido vacío después de cada actualización de WordPress. Consulta el artículo relacionado con el snippet de código en nuestra base de conocimiento.
  3. Elimina los archivos manualmente. La solución más rápida lleva diez segundos vía SFTP: simplemente borra readme.html, license.txt y wp-config-sample.php de la raíz de WordPress. La pega es que las actualizaciones del núcleo de WordPress restauran los archivos. Tienes que acordarte de borrarlos de nuevo tras cada actualización mayor, por lo que un plugin o una regla del servidor web es la mejor solución a largo plazo.

Lo que no deberías hacer

Algunos enfoques que aparecen en entradas de blog antiguas pero que son peores de lo que parecen:

  • Renombrar los archivos. Renombrar readme.html a readme.html.old queda ordenado pero no ayuda. WordPress simplemente vuelve a crear el original en la siguiente actualización y ahora tienes dos archivos en lugar de uno.
  • Establecer los permisos de archivo en 000. Esto bloquea las lecturas en la mayoría de los hosts, pero la siguiente actualización del núcleo restablece los permisos y, en algunos hosts, también rompe la propia actualización si WordPress no puede leer el archivo durante el proceso.
  • Editar los archivos para eliminar el número de versión. Tentador pero inútil. WordPress restaura el original al actualizar e incluso un readme.html editado sigue confirmando que el sitio funciona con WordPress.

El patrón es siempre el mismo: cualquier cosa que viva dentro del directorio de instalación de WordPress y no esté protegida por una regla del servidor web se restablecerá al actualizar. Bloquea a nivel de servidor web o usa un plugin que sepa cómo mantenerse activo entre actualizaciones.

Cómo verificar tu configuración

  1. Abre https://tudominio.com/readme.html en una ventana privada. Resultado esperado: una página 403 Forbidden (o 404 si optaste por la vía de eliminar los archivos).
  2. Misma comprobación para https://tudominio.com/license.txt y https://tudominio.com/wp-config-sample.php.
  3. Si sigues viendo el contenido del archivo, vacía cualquier caché que se sitúe delante del sitio (Cloudflare, Varnish, cachés de página del lado del servidor como LiteSpeed Cache o WP Rocket) e inténtalo de nuevo. Las respuestas en caché pueden ocultar el cambio durante horas.
  4. Lanza un nuevo análisis de InspectWP. La comprobación de un readme.html expuesto en la sección de seguridad debería pasar a verde.

Ya que estás en ello

El mismo tipo de regla FilesMatch o location merece la pena aplicarse a unos cuantos endpoints más que aparecen con regularidad en los análisis de InspectWP: wp-config.php.bak, wp-config.php.swp, .git/, .env, phpinfo.php y cualquier info.php que algún desarrollador haya dejado tras una sesión de depuración. Mismo mecanismo, las mismas cinco líneas de configuración, y eliminas de una sola vez toda una clase de fingerprinting casual y filtraciones de credenciales.

Analiza tu sitio de WordPress ahora

InspectWP analiza tu sitio de WordPress en busca de problemas de seguridad, SEO, cumplimiento del RGPD y rendimiento, gratis.

Analiza tu sitio gratis