Explicador de .htaccess

Pega el archivo y cada línea recibe una frase que dice qué hace. Los patrones de reescritura se desmenuzan pieza por pieza, y las reglas que coinciden con patrones de infección conocidos se marcan para que las mires de cerca.

Búscalo en la carpeta principal del sitio, normalmente public_html, httpdocs o www. Como el nombre empieza con un punto, los gestores de archivos y los programas de FTP lo ocultan hasta que activas “mostrar archivos ocultos”.

Ejemplos

🔒 Your browser does the reading. The file is not uploaded.

Configuración que vive en la carpeta

Un servidor web tiene un archivo de configuración principal que solo puede editar su administrador. En un alojamiento compartido ese no eres tú, así que Apache te da otra vía de entrada. Es un archivo de texto sin formato llamado .htaccess, colocado en una carpeta del sitio, y sus instrucciones se aplican a esa carpeta y a todo lo que cuelga de ella. Los servidores LiteSpeed leen el mismo archivo. nginx no, y lo ignora por completo.

El servidor vuelve a leer el archivo en cada solicitud, así que un cambio surte efecto en el instante en que lo guardas. Un error también. Una sola directiva mal escrita y todas las páginas responden con un error 500 hasta que corriges la línea. Guarda una copia antes de cada edición.

Rara vez eres el único autor. WordPress escribe un bloque entre # BEGIN WordPress y # END WordPress, y los plugins de caché, seguridad e imágenes añaden sus propios bloques marcados. El explicador reconoce los marcadores de unos 25 de ellos, entre ellos WP Rocket, LiteSpeed Cache, Wordfence y Really Simple SSL, y nombra al dueño de cada bloque.

Leer en voz alta una regla de reescritura

mod_rewrite es donde la mayoría se pierde. Toma este par:

RewriteCond %{HTTP_HOST} ^shop\.example\.com$ [NC]
RewriteRule ^products/(\d+)$ https://www.example.com/item?id=$1 [R=301,L]

Se lee como una frase: “Si el host solicitado es shop.example.com, en mayúsculas o minúsculas, y la ruta es products/ seguida de dígitos, envía al visitante de forma permanente a la nueva dirección con esos dígitos como id, y deja de procesar.”

  • Un RewriteCond es una condición sobre una variable del servidor. Solo se aplica al siguiente RewriteRule. Varios seguidos deben cumplirse todos, salvo que uno termine con [OR].
  • La primera parte de un RewriteRule es una expresión regular que se prueba contra la ruta. Los paréntesis capturan texto, y $1, $2 lo reutilizan en el destino. %1 reutiliza una captura de la última condición.
FlagEfecto
LÚltima regla de esta pasada. END se detiene del todo.
R=301Responde con una redirección. 301 es permanente, 302 temporal. Sin R, la reescritura es interna y la barra de direcciones del visitante no cambia.
NCIgnora mayúsculas y minúsculas.
QSAConserva la cadena de consulta original y la añade al final.
F, GRechaza con 403, o responde 410 Gone.
PProxy: obtiene el contenido de otro servidor y lo sirve como propio.

Qué se señala

Los atacantes que consiguen acceso de escritura a un sitio suelen ir a por .htaccess, porque unas pocas líneas ahí pueden redirigir a los visitantes o mantener accesible un script oculto. El explicador compara cada línea con patrones vistos en infecciones reales y le asigna una de dos etiquetas.

Sospechosa, en rojo:

  • una redirección a otro dominio que solo se aplica a los visitantes que llegan desde un buscador, o solo a los teléfonos. El dueño, que escribe la dirección directamente en un ordenador, nunca la ve;
  • un script PHP distinto servido a los rastreadores de los buscadores;
  • AddHandler, AddType o SetHandler que hacen que archivos de imagen o de texto se ejecuten como PHP, o que archivos normales se ejecuten como scripts CGI;
  • php_value auto_prepend_file o auto_append_file que cargan un archivo antes o después de cada script, y allow_url_include;
  • un bloque FilesMatch que deniega todos los archivos .php, .py y .exe, seguido de un bloque que permite una breve lista de archivos PHP que WordPress no incluye.

Revisar, en naranja: líneas dentro del bloque de WordPress que no forman parte de sus reglas estándar, condiciones dirigidas solo a rastreadores o referentes, el flag [P], una página de error alojada en otro dominio, el listado de directorios activado, errores de PHP mostrados a los visitantes, un cortafuegos de aplicación desactivado, líneas de más de 400 caracteres o llenas de base64 o de caracteres codificados, y caracteres invisibles.

También se informa de dos errores estructurales, ya que ambos causan un 500: un bloque como <IfModule> que nunca se cierra, y directivas que solo son legales en la configuración principal del servidor, como DocumentRoot o <VirtualHost>.

El explicador lee texto. No ejecuta las reglas, no puede saber qué módulos tiene cargados tu servidor, y no ve otros archivos .htaccess de carpetas superiores ni la configuración principal, cosas que cambian el resultado. Una señal significa “averigua quién añadió esto”, y los plugins legítimos la disparan de vez en cuando. Un archivo sin señales no prueba que el sitio esté limpio.

Si una línea está señalada y no la escribiste tú

  1. Descarga una copia del archivo como prueba antes de tocar nada.
  2. Comprueba la fecha de modificación del archivo y busca otros archivos cambiados al mismo tiempo, sobre todo archivos PHP en las carpetas de subidas y los nombres que aparecen en las reglas señaladas.
  3. Quita las líneas hostiles y vuelve a cargar el archivo unos minutos después. Si han vuelto, un script del servidor lo está reescribiendo y borrar líneas no bastará.
  4. Cambia las contraseñas del alojamiento, de FTP o SSH, de la base de datos y del administrador del CMS, y actualiza el CMS con todos sus plugins y temas.
  5. Usa la consulta de sitios no seguros para ver si el sitio ya está en una lista de bloqueo de los navegadores, y el rastreo de redirecciones para confirmar que los visitantes acaban donde deben.

Preguntas frecuentes

¿Dónde está el archivo .htaccess?

En la carpeta raíz del sitio, que suele llamarse public_html, httpdocs o www. Las subcarpetas pueden tener el suyo. Los nombres que empiezan por un punto están ocultos por defecto, así que activa “mostrar archivos ocultos” en el administrador de archivos de tu alojamiento o en tu programa de FTP.

¿Por qué mi sitio muestra un error 500 después de editar .htaccess?

Apache se detiene en la primera línea que no puede interpretar. Suele ser una errata en el nombre de una directiva, un bloque que se abrió y nunca se cerró, una directiva que tu alojamiento no permite en .htaccess, o un módulo que no está instalado. Restaura tu copia y vuelve a añadir tus cambios de uno en uno.

¿Qué significa [L,R=301] en un RewriteRule?

R=301 le dice al navegador que vaya a la nueva dirección y la recuerde como permanente. L impide que el servidor aplique más reglas de reescritura a esta solicitud. Juntos, son la redirección permanente estándar.

¿Cómo sé si mi archivo .htaccess ha sido hackeado?

Busca reglas que no añadiste tú: redirecciones a dominios desconocidos, condiciones sobre HTTP_REFERER o HTTP_USER_AGENT, manejadores que ejecutan imágenes como PHP, y auto_prepend_file. Compara el bloque de WordPress con el predeterminado. Esta página señala esos patrones por ti.

¿Funciona .htaccess en nginx?

No. nginx no tiene archivos de configuración por carpeta. Quien administra el servidor debe traducir las reglas a su propia configuración. Algunos alojamientos ponen nginx delante de Apache, y en ese caso .htaccess sigue aplicándose a las solicitudes que llegan a Apache.

¿El archivo que pego se envía a vuestro servidor?

No. El análisis es un script que se ejecuta en tu navegador. Aun así, acostúmbrate a quitar contraseñas y claves secretas de todo lo que pegues en una página web.