PathSentinel Article

Mi web redirige a otra página: cómo encontrar la redirección y quitarla

Tu web salta sola a otra página. Aquí tienes cómo localizar la redirección en el .htaccess, la base de datos o el tema, y cómo quitarla sin romper nada.

Si al escribir tu dominio acabas en una página de apuestas, en una farmacia falsa o en una tienda que no es la tuya, alguien ha metido una redirección dentro de tu sitio. Se puede localizar en una tarde sin ser programador, porque una redirección solo puede salir de cuatro sitios. Aquí tienes cómo confirmar que es real, qué líneas buscar en cada uno de esos cuatro sitios y por qué vuelve a los dos días si te limitas a borrar lo que ves.

Si además la web va lentísima, Google la ha marcado o el hosting te ha avisado, la redirección es solo un síntoma y te conviene el orden completo de la guía de qué hacer cuando te hackean la web.

Primero confirma que la redirección es real y no es tu navegador

Antes de tocar un archivo, descarta que el problema esté en tu ordenador. Pasa más de lo que parece:

  • Abre tu web en una ventana de incógnito y en un navegador distinto del habitual.
  • Pruébala desde el móvil con datos móviles, no con el wifi de la oficina. Si el router o el DNS de tu red están tocados, con wifi verías lo mismo.
  • Mira las extensiones del navegador en chrome://extensions. Una extensión de cupones o de «compra segura» puede secuestrar dominios.
  • Comprueba el archivo hosts: C:WindowsSystem32driversetchosts en Windows, /etc/hosts en Mac o Linux. Tu dominio no debería aparecer ahí.

La prueba que zanja la duda es pedirle la página al servidor sin navegador de por medio, desde el terminal de tu ordenador:

curl -sI https://tudominio.es | grep -i "^location"

Si aparece una línea location: hacia un dominio que no es el tuyo, la redirección la hace tu servidor. Si no aparece nada, todavía no cantes victoria: muchas se disparan solo con visitantes de móvil o con quien llega desde Google, precisamente para que el dueño de la web no las vea. Hazte pasar por esos casos:

curl -sI -A "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15" https://tudominio.es
curl -sI -e "https://www.google.com/" https://tudominio.es

Ese comportamiento selectivo es tan característico que le hemos dedicado un artículo aparte sobre las webs que solo fallan en el móvil, porque casi siempre significa lo mismo.

Si ninguna prueba reproduce el salto pero en un navegador normal sí ocurre, lo lanza JavaScript dentro de la página. Abre la web con las herramientas de desarrollador (F12), pestaña Red, marca «Conservar registro» y recarga: ahí verás el dominio que te está llevando.

Los cuatro sitios donde se esconde una redirección maliciosa

Da igual lo enrevesado que parezca el ataque, la instrucción de redirigir vive en uno de estos cuatro sitios:

  1. Reglas del servidor web: el archivo .htaccess en Apache, o la configuración del sitio en nginx.
  2. Archivos PHP: index.php, wp-config.php, el functions.php del tema, plugins falsos o la carpeta mu-plugins.
  3. La base de datos: las opciones siteurl y home, o un <script> inyectado dentro del contenido de las entradas.
  4. JavaScript cargado desde fuera: un script de terceros, un anuncio o una etiqueta de seguimiento que sirve código distinto según quién mire.

La prueba con curl ya te ha dicho por dónde empezar. Si viste una cabecera location con un 301 o un 302, el culpable está en los puntos 1 o 2. Si el servidor devolvió un 200 con tu HTML de siempre y el salto ocurre después, mira los puntos 3 y 4.

Un aviso antes de seguir: haz una copia de los archivos y de la base de datos tal y como están ahora, infectados y todo, y guárdala aparte. Si luego hay que averiguar cómo entraron, es la única prueba que vas a tener. Con eso hecho ya puedes borrar sin miedo; el procedimiento completo está en la guía de cómo limpiar un WordPress hackeado paso a paso.

Revisar .htaccess e index.php: qué líneas no deberían estar ahí

Abre el .htaccess de la raíz con el editor de archivos del hosting o por SFTP. El bloque legítimo de WordPress es corto, empieza por # BEGIN WordPress, termina por # END WordPress y manda todo a index.php. Lo que no debería estar ahí:

  • Condiciones sobre quién visita, del tipo RewriteCond %{HTTP_USER_AGENT} (android|iphone|ipad) o RewriteCond %{HTTP_REFERER} (google|bing|yahoo), seguidas de una RewriteRule que apunta fuera.
  • Cualquier RewriteRule cuyo destino sea un dominio que no reconoces.
  • Directivas php_value auto_prepend_file o auto_append_file: cargan un archivo PHP antes de cada página, y ese archivo suele ser la puerta trasera.

Dos trampas clásicas. La primera: dejan cientos de líneas en blanco antes del código para que veas el bloque de WordPress y creas que está limpio, así que baja siempre hasta el final del archivo. La segunda: hay un .htaccess por carpeta, y en wp-content/uploads no debería haber ninguna regla de reescritura. Con acceso SSH:

find . -name ".htaccess" -mtime -30 -ls

Con index.php la comprobación es más simple todavía. El de la raíz tiene una docena de líneas, empieza por <?php sin nada delante y acaba con un require de wp-blog-header.php. Si ves ahí un eval(, un base64_decode(, un @include de un archivo con nombre raro o una tira larguísima de caracteres, es inyección: no pierdas tiempo limpiándolo, descarga el zip oficial desde es.wordpress.org y sustituye el archivo entero.

Si tu hosting usa nginx, el .htaccess ni se lee: la redirección estará en la configuración del sitio y, salvo que tengas un servidor propio, tendrás que pedírsela al soporte.

Buscar la inyección en la base de datos: wp_options, siteurl y home

Entra en phpMyAdmin desde el panel del hosting, selecciona la base de datos de la web y ve a la pestaña SQL. La primera consulta, siempre, es esta (cambia wp_ si tu instalación usa otro prefijo):

SELECT option_name, option_value FROM wp_options
WHERE option_name IN ('siteurl','home');

Ahí tiene que aparecer tu dominio con https:// y nada más. Si aparece otro, ya has encontrado la redirección: corrígelo y la web vuelve. Ojo, porque esos dos valores también se pueden forzar desde wp-config.php con las constantes WP_HOME y WP_SITEURL.

Si eso está bien, busca scripts metidos dentro del contenido y opciones sospechosas por tamaño, que es la forma más rápida de encontrar un bloque de código escondido entre ajustes normales:

SELECT ID, post_title FROM wp_posts
WHERE post_content LIKE '%<script%' AND post_status = 'publish';

SELECT option_name, LENGTH(option_value) AS tam FROM wp_options
WHERE autoload = 'yes' ORDER BY tam DESC LIMIT 20;

Con WP-CLI, un comando busca el dominio del atacante en todas las tablas: wp db search "dominio-que-no-conoces.com" --all-tables. Exporta la base de datos antes de editar nada: un UPDATE mal hecho se lleva por delante contenido que no recuperas.

Scripts inyectados en el tema y en la cabecera

Si la redirección la lanza JavaScript, el script sale de alguno de estos sitios, por orden de probabilidad:

  • header.php, footer.php y functions.php del tema activo, y también los del tema padre si usas uno hijo.
  • La carpeta wp-content/mu-plugins: todo lo que hay ahí se ejecuta sin aparecer como plugin activo, así que es el escondite favorito. Si no la creaste tú y contiene un PHP suelto, sospecha.
  • Los campos de «código en la cabecera» de las opciones del tema, los widgets de HTML personalizado y los plugins de insertar cabeceras y pies.
  • Tu contenedor de Google Tag Manager, si alguien más tiene acceso.

Con acceso SSH, una búsqueda por patrones te ahorra abrir archivos uno a uno:

grep -rn --include="*.php" -E "eval(|base64_decode|gzinflate|str_rot13" wp-content/ | head -50

Aquí hace falta criterio, porque base64_decode aparece de forma legítima en plugins serios. Lo que delata a un ataque es la suma de señales: código comprimido en una sola línea kilométrica, nombres de variables sin sentido y una fecha de modificación distinta a la de los archivos vecinos.

Lo más fiable es comparar con el original. Con WP-CLI, wp core verify-checksums y wp plugin verify-checksums --all hacen ese trabajo para el núcleo y los plugins del repositorio oficial; los temas y los plugins de pago hay que descargarlos de su fuente y compararlos a mano.

Cuándo la redirección viene de un plugin o de un anuncio mal configurado

No todo es un ataque, y conviene descartarlo antes de borrar. Un plugin de redirecciones con una regla mal puesta, un plugin de geolocalización que manda a los visitantes de otro país a otra web o un script publicitario con salto automático dan el mismo síntoma.

La prueba definitiva es apagar todos los plugins de golpe: por SFTP, renombra wp-content/plugins a plugins-off y recarga. Si la redirección desaparece, deja el nombre correcto y ve desactivando de uno en uno desde Plugins > Plugins instalados hasta dar con el responsable. Hazlo fuera de horario, porque durante esos minutos la web se ve rota.

Si el salto solo ocurre en algunas visitas y cada vez a un dominio distinto, huele a publicidad de terceros: mira en la pestaña Red de qué dominio viene el script y quítalo mientras hablas con el proveedor.

Y aquí va la parte honesta: si el culpable resulta ser una extensión de tu navegador, un plugin de redirecciones tuyo o una etiqueta publicitaria, ya has terminado. No hay malware, no hay nada que notificar y no necesitas contratar ninguna limpieza. Guarda el dinero.

Por qué vuelve a los dos días aunque la hayas borrado

Cuando sí era un ataque y la redirección reaparece sola, no es que se te haya escapado una línea: el atacante dejó un segundo archivo cuya única función es volver a escribirla. La redirección es el síntoma; lo que hay que encontrar es el reinstalador. Suele ser un archivo PHP en wp-content/uploads, un plugin falso que figura como desactivado, algo en mu-plugins, una tarea programada o un administrador nuevo con nombre inofensivo. Cómo peinar cada uno de esos sitios lo tienes en el artículo sobre cómo buscar puertas traseras en tu web.

Añade tres comprobaciones que casi nadie hace:

  • Las tareas programadas. En el panel del hosting, la sección de Cron Jobs; dentro de WordPress, wp cron event list.
  • Las otras webs de la misma cuenta de hosting. Si varios WordPress cuelgan del mismo usuario del servidor, la infección salta de carpeta en carpeta y limpiar una sola no sirve de nada.
  • Tu propio ordenador. Muchas entradas empiezan con una contraseña de FTP robada por un programa espía en el equipo del administrador.

Cambia después, por este orden, las contraseñas de FTP y SFTP, la del panel, la de la base de datos (actualizando wp-config.php) y las de todos los administradores; y regenera las claves de seguridad de wp-config.php para cerrar las sesiones abiertas del atacante.

¿Cuándo dejar de intentarlo tú? Si has limpiado dos veces y ha vuelto, si hay varias webs afectadas en el mismo servidor o si la web cobra o guarda datos de clientes. Una limpieza profesional con revisión de puertas traseras ronda los 500 euros y ahorra semanas de reinfecciones. Si es una web pequeña, encontraste una línea en el .htaccess y llevas dos semanas sin que vuelva, ya está.

Termines como termines, la comprobación final no la hagas desde tu navegador, que tiene la web en caché y te va a mentir. Pasa PathScan y comprueba desde fuera si tu web sigue redirigiendo: es gratuito, no hace falta registrarse y no toca nada de tu instalación, solo mira tu dominio como lo haría un visitante cualquiera.