Cómo funciona esta comprobación
Scanaris pide nueve nombres de archivo que la gente usa una y otra vez para guardar copias de seguridad en la raíz de la web: backup.zip, backup.tar.gz, website.zip, www.zip, public_html.zip, site.zip, database.sql, dump.sql y db.sql. Para cada uno comprueba que la respuesta es un archivo real y no la página genérica de tu web: mira el tipo de contenido y, en el caso de los volcados SQL, que el texto parece SQL. Todos los hallazgos son de severidad crítica, porque un archivo así contiene o bien el código completo del sitio o bien la base de datos entera.
Por qué importa
Un backup.zip accesible es tu proyecto completo: código, configuración, claves que hubiera en los archivos y, a menudo, una copia de la base de datos dentro. Un dump.sql es la base de datos tal cual: usuarios, correos, contraseñas cifradas (que se pueden atacar sin prisa), pedidos, mensajes. No hace falta ninguna técnica: es una descarga. Y los escáneres automáticos prueban exactamente estos nombres contra todos los dominios que encuentran, así que "nadie conoce la URL" no es una protección.
Por qué ocurre
Por comodidad en un mal momento: antes de una migración o una actualización se comprime la carpeta de la web "por si acaso" y se deja ahí mismo. O un plugin de copias de seguridad escribe en una carpeta pública. O una exportación de la base de datos se guarda junto al código para pasársela a alguien. En un servidor que sirve la raíz del proyecto, cualquier archivo que caiga ahí es público al instante.
Cómo arreglarlo
- Borra el archivo ahora y actúa como si se hubiera descargado: rota todas las claves y contraseñas que contuviera y, si había datos personales, valora la obligación de notificar.
- Mueve las copias fuera del directorio público. Las copias de seguridad van a un almacenamiento aparte (un bucket privado, otro servidor), nunca a una carpeta que sirva el servidor web.
- Configura la herramienta de copias para que escriba fuera de la raíz web. Los plugins de WordPress suelen permitir elegir la carpeta o enviar a un servicio externo.
- Bloquea las extensiones en el servidor como segunda barrera. En nginx:
location ~* \.(zip|tar|gz|sql|bak)$ { deny all; }. En Apache, unFilesMatchequivalente conRequire all denied. Si legítimamente ofreces descargas comprimidas, limítalas a una carpeta concreta. - Revisa los registros de acceso buscando peticiones con 200 a estos nombres: te dirán si alguien llegó antes.
Comprueba que está arreglado
for p in backup.zip backup.tar.gz website.zip www.zip public_html.zip site.zip database.sql dump.sql db.sql; do
printf "%-18s " "$p"; curl -s -o /dev/null -w "%{http_code} %{content_type}\n" "https://tudominio.com/$p"
done
Lo esperado es 404 o 403. Un 200 con text/html en una aplicación de una sola página es su HTML genérico; un 200 con application/zip, application/octet-stream o text/plain es el archivo real.
Preguntas frecuentes
Mi copia tiene un nombre que nadie adivinaría.
Las herramientas de ataque prueban miles de nombres y combinaciones con el dominio, la fecha y palabras como "old" o "bak". Un nombre raro reduce el riesgo pero no lo elimina; la solución es que no esté en una carpeta pública.
¿Y si el archivo está protegido con contraseña?
Un ZIP con contraseña se descarga igual y se ataca sin límite de intentos en el ordenador del atacante. Sigue siendo un hallazgo crítico.
El check solo mira la raíz. ¿Y las subcarpetas?
Correcto, estos nueve nombres se prueban en la raíz. Los listados de directorio abiertos, que mide otro check, son la forma habitual de encontrar copias en subcarpetas; cerrarlos y bloquear las extensiones cubre el resto.