En resumen: los archivos de copia de seguridad en el webroot, es decir, volcados de bases de datos (.sql), archivos comprimidos (.zip, .tar.gz) y copias de respaldo (.bak, .old, ~), puede descargarlos cualquiera que conozca o adivine el nombre del archivo. Busque con regularidad estos archivos con find, traslade las copias fuera del directorio público, bloquee en el servidor web las extensiones típicas y compruebe en los logs de acceso si ya se han descargado.
La copia de seguridad que se convierte en fuga
Poco antes de una actualización, alguien genera deprisa una copia: backup.zip en el directorio principal y, al lado, datenbank.sql. La actualización sale bien y los archivos se quedan ahí. Meses después siguen estando, con todo el código, todos los datos de clientes y las credenciales del sitio web.
Este patrón figura entre los hallazgos más frecuentes en las auditorías de servidores web. No necesita ningún exploit ni vulnerabilidad en PHP. Un servidor web sirve desde el webroot lo que haya allí y los archivos comprimidos o SQL no los ejecuta, sino que los ofrece para su descarga.
Un archivo comprimido del sitio web contiene además no solo datos, sino también el código con su configuración. Quien lo descarga puede buscar vulnerabilidades con calma y conoce las credenciales de la base de datos.
Los escáneres automatizados buscan de forma dirigida nombres típicos como backup.zip, site.tar.gz o dump.sql, a menudo combinados con el nombre del dominio o una fecha. Quien cree que un nombre de archivo inusual protege subestima lo sistemática que es esta búsqueda.
A qué archivos nos referimos
Los archivos de copia de seguridad en el webroot aparecen de varias formas:
| Tipo | Extensiones típicas | Qué contienen |
|---|---|---|
| Volcados de bases de datos | .sql, .sql.gz, .dump |
Datos de clientes, pedidos, hashes de contraseñas, ajustes |
| Archivos comprimidos del sitio web | .zip, .tar, .tar.gz, .tgz, .rar, .7z |
Todo el código, configuración, subidas |
| Copias de archivos individuales | .bak, .old, .orig, .save, .php~, .copy |
A menudo archivos de configuración con credenciales |
| Restos de editores | .swp, .swo, ~ al final |
Partes de archivos que se estaban editando |
| Copias de seguridad de plugins | Subcarpetas propias en el CMS | Copias completas, en parte con nombres adivinables |
Especialmente delicadas son las copias de archivos de configuración. El archivo original config.php lo ejecuta el servidor y su contenido permanece oculto. La copia config.php.bak la sirve como texto, con la contraseña de la base de datos incluida.
Encontrar copias de seguridad en el webroot: búsqueda en el servidor
La búsqueda siguiente lista los archivos sospechosos por debajo de los webroots, con fecha y tamaño. Adapte las rutas a su servidor:
find /var/www /srv/www -type f \( \
-iname '*.sql' -o -iname '*.sql.gz' -o -iname '*.dump' -o \
-iname '*.zip' -o -iname '*.tar' -o -iname '*.tar.gz' -o -iname '*.tgz' -o \
-iname '*.rar' -o -iname '*.7z' -o \
-iname '*.bak' -o -iname '*.old' -o -iname '*.orig' -o -iname '*.save' -o \
-iname '*~' -o -iname '*.swp' \) \
-printf '%TY-%Tm-%Td %10s %p\n' 2>/dev/null | sort
No todos los resultados son un problema. Algunos archivos comprimidos se ofrecen deliberadamente para su descarga, por ejemplo manuales. Pero cada archivo merece una decisión consciente. Preste especial atención a los archivos grandes y a las carpetas de plugins de copia de seguridad. En un hosting compartido sin acceso a shell, ayudan la vista de archivos del panel de hosting o una consulta por SFTP.
Si encuentra en el webroot un volcado de base de datos con datos de clientes, sáquelo de inmediato del directorio público y asegure los logs de acceso antes de que se roten. Solo después aclare si el archivo se descargó.
¿Se ha descargado ya el archivo?
La respuesta está en los logs de acceso del servidor web. Se buscan descargas correctas, es decir, estado 200, de los archivos encontrados:
# Descargas correctas de extensiones típicas de copias de seguridad (formato de log Combined)
zgrep -hE '\.(sql|sql\.gz|zip|tar|tgz|gz|bak|old|7z|rar)[ ?]' /var/log/nginx/access.log* \
| awk '$9 == 200 {print $4, $1, $7, $10}'
La salida muestra el momento, la dirección, la ruta y el tamaño de la respuesta. Si el tamaño transferido coincide con el tamaño del archivo, el archivo se descargó por completo. Hasta cuándo se remontan los logs depende de la rotación. Si no llegan hasta la fecha de creación del archivo, no puede descartarse una descarga anterior. Lo describe con detalle Analizar los logs del servidor web tras un ataque. Sin acceso a los logs sin procesar, por ejemplo en hosting compartido, pida al proveedor los logs del período correspondiente.
Si se descargó un volcado con datos personales, o no puede descartarse, comienza la evaluación de una obligación de notificación. Los fundamentos los resume Obligación de notificación del RGPD: 72 horas tras el incidente; la valoración en cada caso corresponde a su delegado de protección de datos. Las credenciales de archivos descargados debe sustituirlas en cualquier caso.
Plugins de copia de seguridad, paneles y mudanzas
Muchos hallazgos se deben a plugins de copia de seguridad de CMS y tiendas. A menudo guardan las copias en una subcarpeta del webroot, en parte con nombres formados por fecha y dominio que pueden adivinarse. Compruebe en cada plugin tres ajustes: ¿adónde se guarda la copia? ¿Se borran las copias locales tras subirlas a un destino externo? ¿Está la carpeta local protegida frente a la descarga directa?
Las copias de los paneles de hosting suelen estar fuera del webroot, por ejemplo en el directorio home. Se vuelve problemático cuando alguien copia una de esas copias al webroot porque la descarga en el navegador es más cómoda que por SFTP. Para las mudanzas rige por ello: transferencia por SFTP o directamente entre servidores, nunca mediante un enlace público.
Si agencias o proveedores de servicios se ocupan de sus sitios web, esta regla debería constar también en el contrato, junto con la obligación de limpiar tras los trabajos de mantenimiento. Encontrará indicaciones en Contratos con proveedores de TI: regular con claridad las obligaciones de seguridad.
Prevenir de forma duradera: lugar de almacenamiento y bloqueos
Para que el problema no se repita, hacen falta dos niveles. El primero es organizativo: las copias tienen un lugar fijo fuera del webroot y, además, fuera del servidor. Cómo es una copia fiable lo describe la guía Copias de seguridad según la regla 3-2-1.
El segundo nivel es técnico: el servidor web deniega por principio las extensiones típicas de copias de seguridad, aunque alguna vez se quede un archivo.
location ~* \.(sql|sql\.gz|dump|bak|old|orig|save|swp|swo)$ {
return 404;
}
location ~ ~$ {
return 404;
}
Los archivos comprimidos como .zip solo se bloquean si su sitio web no ofrece descargas en ese formato, o de forma dirigida en los directorios en los que no hay descargas. Ayudan además una búsqueda automática periódica con aviso y una breve regla en el equipo: ninguna copia de seguridad ni copia de archivos en el webroot, ni siquiera durante cinco minutos. Casos relacionados, como los archivos de configuración ocultos, los trata Proteger correctamente las credenciales y los archivos .env.
¿Cómo ayuda PHP SOS en concreto?
- Examinamos sus webroots en busca de volcados, archivos comprimidos, copias y copias de seguridad de plugins y valoramos cada hallazgo.
- Comprobamos con los logs de acceso si se descargaron archivos y documentamos el resultado para su evaluación de protección de datos.
- Configuramos bloqueos en el servidor web y una búsqueda automática periódica.
- Trasladamos las copias de seguridad a un lugar protegido fuera del webroot.
Estos trabajos forman parte de nuestro refuerzo de servidores web PHP.
Preguntas frecuentes
¿Por qué acaban las copias de seguridad en el webroot?
Casi siempre por comodidad: se genera un volcado para una mudanza, un plugin guarda copias en su propia carpeta o, antes de un cambio, se hace deprisa una copia de un archivo con la extensión .bak. Después, el archivo cae en el olvido.
¿Cómo de peligroso es un archivo como config.php.bak?
Muy peligroso. Un archivo con la extensión .php lo ejecuta el servidor y su contenido permanece oculto. Una copia con otra extensión, en cambio, el servidor suele servirla como texto, con la contraseña de la base de datos y las claves incluidas.
¿Es una brecha de datos un volcado de base de datos accesible públicamente?
Si contiene datos personales y se descargó, o no puede descartarse una descarga, puede entrar en consideración una obligación de notificación conforme al RGPD. La valoración en cada caso concreto corresponde a su delegado de protección de datos o a su asesoría jurídica.
¿Dónde deberían estar entonces las copias de seguridad?
Fuera del webroot y, además, fuera del servidor, según la regla 3-2-1. Al menos una copia debería guardarse de modo que el propio servidor web no pueda borrarla ni modificarla.