Lo que mostraron los logs
Nuestro sitio corre en Cloud Run detrás del balanceador de carga de Google, que registra cada solicitud. Desde el 4 de octubre, cuando el sitio se mudó ahí, leemos esos logs con un script pequeño, ai_traffic.py, que agrupa las solicitudes según el rastreador que nombra su user agent: GPTBot y ChatGPT-User de OpenAI, ClaudeBot y Claude-User de Anthropic, PerplexityBot, Applebot, CCBot y otros, con Googlebot y bingbot como referencia. Diecisiete nombres en total.
Del 4 al 17 de octubre de 2026 encontró 1,835 solicitudes de páginas con esos nombres. El sitio respondió 1,170 con una página. Rechazó las otras 665, y 454 de ellas pedían archivos que ningún sitio público debería entregar.
- solicitudes de páginas con nombre de rastreador, del 4 al 17 de octubre
- 1,835
- pedían secretos, llaves o archivos de configuración
- 454
- tenían .env en la ruta
- 299
- nombres de rastreador aparecieron en esas solicitudes
- 17 de 17
Lo que pidieron
Las 454 solicitudes probaron 181 rutas distintas. Casi todas eran variaciones de unas pocas ideas:
- Archivos
.env, en 299 solicitudes:/.env,/.env.local,/.env.production, y los mismos nombres dentro de/app,/srco/public. Muchos frameworks guardan ahí llaves de API y contraseñas de la base de datos mientras desarrollas. - Rutas que empiezan con
/@fs/, en 62. Así entrega archivos del disco el servidor de desarrollo de Vite, y un aviso de seguridad de 2025 (en inglés) mostró que podía entregar cualquier archivo cuando ese servidor quedaba expuesto a la red. - Credenciales de la nube, en 61:
/google-credentials.json,/firebase-credentials.json,/keys/service-account.json. - Archivos de procesos de Linux como
/proc/self/environ, que guarda las variables de entorno de un programa en ejecución, en 38. - Llaves SSH y configuración de git, como
/.ssh/id_rsa,/.git/configy/.git-credentials, en 27.
Llegaron en cuatro tandas: 54 el 6 de octubre, 72 el 8, 190 el 10 y 138 el 16. Parece una herramienta recorriendo una lista de rutas. Un rastreador que lee un sitio sigue sus enlaces y su sitemap.
Todos los nombres eran prestados
Los 17 nombres aparecieron en esas solicitudes, Googlebot incluido, con 40. Con cinco nombres nadie recibió una página: se rechazó cada solicitud que decía PerplexityBot, Perplexity-User, DuckAssistBot, CCBot o MistralAI-User.
| Nombre | Empresa | Respondidas | Rechazadas | Pedían secretos |
|---|---|---|---|---|
| GPTBot | OpenAI | 93 | 41 | 27 |
| OAI-SearchBot | OpenAI | 54 | 43 | 29 |
| ChatGPT-User | OpenAI | 11 | 51 | 34 |
| ClaudeBot | Anthropic | 386 | 41 | 22 |
| Claude-SearchBot | Anthropic | 1 | 41 | 29 |
| Claude-User | Anthropic | 3 | 42 | 32 |
| PerplexityBot | Perplexity | 0 | 44 | 26 |
| Perplexity-User | Perplexity | 0 | 39 | 28 |
| MistralAI-User | Mistral | 0 | 18 | 9 |
| DuckAssistBot | DuckDuckGo | 0 | 44 | 34 |
| Applebot | Apple | 141 | 37 | 21 |
| CCBot | Common Crawl | 0 | 35 | 27 |
| meta-externalagent | Meta | 16 | 31 | 23 |
| Bytespider | ByteDance | 6 | 44 | 33 |
| Amazonbot | Amazon | 131 | 31 | 22 |
| Googlebot | 291 | 57 | 40 | |
| bingbot | Microsoft | 37 | 26 | 18 |
Los escáneres no inventaron sus propios user agents. Usaron 21 textos distintos, y 8 eran idénticos, letra por letra, a textos que leyeron nuestras páginas esos mismos días. Leer el user agent no basta para separarlos.
| Respondidas con página | 1,170 solicitudes |
|---|---|
| Rechazadas, otras rutas | 211 solicitudes |
| Rechazadas, pedían secretos | 454 solicitudes |
Cómo distinguir un rastreador de un nombre prestado
Un user agent es lo que el remitente dice de sí mismo. Cualquiera puede poner GPTBot/1.4 en un encabezado. Lo que un escáner no puede tomar prestado es la dirección desde la que envía, y las empresas grandes dicen cómo revisar la suya:
- 01Google: busca el DNS inverso de la IP, revisa que el nombre termine en
googlebot.com,google.comogoogleusercontent.com, luego busca ese nombre y confirma que devuelve la misma IP. Google también publica los rangos de IP de sus rastreadores en archivos JSON (Verificar Googlebot, en inglés). - 02OpenAI: una lista de IPs por rastreador, en
openai.com/gptbot.json,openai.com/searchbot.jsonyopenai.com/chatgpt-user.json(los rastreadores de OpenAI, en inglés). - 03Anthropic: una lista en
claude.com/crawling/bots.json, y una IP de origen que esté en ella indica que la solicitud viene de Anthropic (los rastreadores de Anthropic, en inglés).
Nuestro script no revisa IPs: a propósito, nunca se las pide a los logs. Por eso trata el user agent como lo que dice el remitente y deja que la respuesta del sitio decida qué cuenta. Una solicitud es una página leída solo si el sitio la respondió con una página.
for _, user_agent, url, _, status in rows:
crawler = crawler_of(user_agent)
if not crawler or NOT_A_PAGE.search(url):
continue
if status.startswith("2") or status == "304":
read[crawler] += 1
pages[crawler][path_of(url)] += 1
else:
refused[crawler] += 1Eso hace de nuestras cifras de "respondidas" un techo: un escáner que pidiera una página que sí existe también contaría. Antes de una decisión que dependa de ellas, como bloquear o permitir un rastreador, revisa la IP.
Lo que respondió nuestro sitio
De las 454 solicitudes que pedían secretos, 441 recibieron un 404 Not Found. Dos pidieron /admin/.env y el sitio las mandó a la página de inicio de sesión del admin, como hace con cualquier dirección bajo /admin sin sesión. Las otras 11, trucos de rutas como /media../.env, no tienen estado en el log.
Ninguno de esos archivos existe donde corre el sitio, y es a propósito. La imagen que corre Cloud Run lleva lo que produce el build, y .dockerignore deja fuera todos los archivos .env:
node_modules
.next
.env*
!.env.example
Los secretos viven en Secret Manager de Google, y Cloud Run se los entrega a la app como variables de entorno cuando arranca. No hay archivo que encontrar, así que un 404 es la respuesta correcta, y además barata: sin reglas de firewall y sin una lista de user agents malos que mantener al día.
No bloquees por user agent
Bloquear un user agent detiene al rastreador honesto y no al escáner, que puede usar cualquier nombre. Usa robots.txt para decirles a los rastreadores reales qué leer, y asegúrate de que ningún secreto se pueda alcanzar con ningún nombre.
Lo que le diríamos a quien lee sus logs
Un user agent es lo que el remitente dice de sí mismo.
- Cuenta como visitas solo las solicitudes respondidas. El nombre de un rastreador en un 404 para
/.envhabla de escáneres, no de búsqueda con IA. - Antes de bloquear o permitir un rastreador, revisa su IP en la lista que publica la empresa o con su DNS inverso.
- Deja los secretos fuera de lo que despliegas, y revisa la imagen, no solo el repositorio.
- Lee los logs del servidor, no solo tu analítica. La analítica que corre en el navegador no muestra estas solicitudes: las herramientas detrás de ellas piden rutas, no cargan páginas.
Si estás construyendo una plataforma web y quieres sus secretos, logs y despliegues armados así desde el primer día, mira qué te sirve o envíanos tu proyecto.


