Guías de seguridad
¿Dejaste un archivo de secretos en un directorio público? Audita tu webroot
Un token o archivo de credenciales en el directorio público (webroot) de tu web puede descargarlo cualquiera por URL. El error clásico, la trampa de la plantilla que abre el mismo agujero en todos los sitios, y cómo auditarlo y cerrarlo.
Para: cualquiera que ejecute varios sitios en hosting compartido/de alquiler o un VPS, desplegando en directorios públicos (public/, public_html/, htdocs/, etc.). Sin pasos de ataque — solo auditar tu propio servidor y cerrar los agujeros. Para proteger el propio .env, ver proteger el .env en hosting compartido.
La visión de este sitio: dónde lo pones ES el control de acceso
Los secretos se filtran más por accidentes de ubicación que por ataques ingeniosos. El webroot es "un sitio del que cualquiera puede venir a descargar por URL". Pon un secreto ahí y hasta la contraseña de servidor más fuerte deja de tener sentido. La base de este sitio es mantener los secretos fuera tanto del webroot como de git (→ guardar secretos con seguridad). La idea es simple: el directorio público es una estantería pública. Pon en ella solo cosas que no te importe que se vean.
public/ = descargable por cualquiera vía URL
OK colocar
imágenes, CSS, JS — recursos públicos
Nunca colocar
.env, token.json, .sql, .git, .bak
Por encima de la raíz de la app = no servido
Pon aquí
secretos, tokens, credenciales, copias de seguridad. Permisos 600 (solo lectura del propietario). Inalcanzable por URL.
Por qué ocurren los "restos en el directorio público"
El patrón común es un archivo colocado por comodidad, o uno que vino dentro de un boilerplate, que se queda público en silencio.
Por ejemplo, un JSON que contiene un token de acceso para una integración de terceros permanece bajo public/ durante mucho tiempo — y si es de una plantilla compartida, el mismo archivo se copia al mismo sitio en muchos sitios web, así que todos comparten el mismo agujero. Arreglar un sitio no sirve de nada si los demás están abiertos. Igual de peligrosos: .env olvidados, copias de seguridad de bases de datos (.sql), un directorio .git, copias de seguridad del editor (*.bak) y atajos (relacionado: path traversal · un .env entero expuesto).
Audita tu propio servidor
Primero, saca a la luz de forma mecánica "cualquier archivo con aspecto de secreto en mi propio directorio público". Esto es inspeccionar tus propios activos, no fisgonear el sitio de otra persona.
Busca bajo los directorios públicos archivos con aspecto de secreto
public/ (JSON de token/credenciales, .env, claves, atajos).Asume la propagación — amplía a cada servidor y sitio
Decide por archivo si de verdad necesita ser público
# audita bajo tus propios directorios públicos (inspeccionando tus propios activos)
find ~ -path '*/public/*' \( -iname '*token*.json' -o -iname '*credential*.json' \
-o -iname '*.bak' -o -iname '*.sql' -o -iname '.env*' \) 2>/dev/null
# un directorio .git expuesto también es peligroso
find ~ -path '*/public/*/.git' -maxdepth 8 2>/dev/nullQué hacer cuando encuentras uno
Haz tres cosas como un conjunto — quitar, revocar, mover. Sáltate una y el agujero no queda del todo cerrado.
Quita del webroot para que la URL no pueda descargarlo
Revoca/reemite cualquier clave o token que pueda haberse filtrado
Mantén los secretos fuera del webroot con permisos 600
La ubicación en la que cae la gente (peligrosa)
- un token JSON para una integración está en
public/ - un archivo de secretos que vino en el boilerplate se queda público
- copias de seguridad (
.sql/.bak) o.gitdejadas bajo el directorio público - arreglar un sitio y darlo por "resuelto"
La ubicación correcta
- el directorio público contiene solo cosas compartibles públicamente
- los secretos viven fuera del webroot con permisos 600
- las extensiones sensibles están denegadas de ser servidas
- encuentra uno y audita cada servidor y sitio
Convierte 'solo cosas seguras para publicar' en una regla permanente
Las reglas vencen a los arreglos puntuales. Decide que el directorio público es una estantería pública, y como regla nunca pongas ahí secretos, copias de seguridad, datos de control de versiones (.git) ni archivos de configuración. Cuando actualices un boilerplate, quita el secreto de la propia plantilla — de lo contrario, cada sitio que produzcas en masa después seguirá copiando el mismo agujero.
Qué hace este sitio
La base de este sitio es mantener los secretos — claves, tokens, cadenas de conexión — fuera tanto del directorio público como del repositorio de código. Los artefactos de despliegue contienen solo recursos públicos compilados; los secretos se guardan como variables de entorno del entorno de ejecución, en un sitio que no se sirve. La razón: la clase de incidente de este artículo es el típico "un solo resto, y una sola URL lo filtra todo". Diseñamos la propia ubicación como control de acceso, y ejecutamos esta auditoría con la misma cadencia que el inventario de respuesta a vulnerabilidades.
Sigue leyendo
- Stacks: proteger el .env en hosting compartido · el manual de respuesta a vulnerabilidades (inventario)
- Glosario: archivos .env y secretos · path traversal
- Incidente: un .env entero expuesto
- Almacenamiento: guardar secretos con seguridad
FAQ
Q¿Por qué es peligroso poner archivos en un directorio público?
Cualquier cosa en el directorio público de la web (webroot — public/, public_html/, etc.) puede descargarla quien acierte con su URL. Un JSON de token/credenciales, un .env, una copia de seguridad o un archivo de clave olvidados se recuperan antes de que nadie se dé cuenta, provocando un daño inmediato. El directorio público debería contener solo cosas que es seguro que sean públicas.
QSi encuentro uno en un sitio, ¿debería revisar los demás?
Sí. Si produces sitios en masa a partir de una plantilla o boilerplate compartido, lo olvidado suele estar propagado por todos ellos. Encuentra uno y audita cada sitio y servidor del mismo origen.
Q¿Qué hago cuando encuentro uno?
1) Quita el archivo del webroot para que devuelva 404 por URL. 2) Renueva/revoca cualquier token o clave que pueda haberse filtrado (asume que se filtró). 3) En adelante, mantén los secretos fuera del webroot con permisos 600 (solo lectura del propietario). Haz las tres cosas como un conjunto.