El desastre de facturación de S3: cómo arruinarse solo con el nombre del bucket
Al finalizar este tema
Comprenderá por qué la estructura de facturación de S3 basada en solicitudes puede ser peligrosa y cómo prevenirlo.
Me dijeron que S3 era barato
AWS S3 es un servicio de almacenamiento de archivos. El costo de almacenamiento es de aproximadamente 23 al mes.
Sin embargo, además del costo de almacenamiento, S3 tiene un costo por solicitud. Se cobra por cada solicitud: al leer un archivo (GET), al listar objetos (LIST) o al subir un archivo (PUT).
40.000**.
Caso real: el nombre del bucket se hizo público
Este es un caso que ocurrió realmente en 2024. Un desarrollador creó un bucket de S3 y escribió su nombre directamente en el código fuente (hardcoded). Este código se subió a un repositorio público de GitHub.
Alguien descubrió el nombre de este bucket y ejecutó un bot para enviar cientos de millones de solicitudes GET a archivos que no existen.
GET https://my-bucket.s3.amazonaws.com/random-file-001
GET https://my-bucket.s3.amazonaws.com/random-file-002
... (se repite cientos de millones de veces)Incluso si no existe un archivo, S3 responde con "404 Not Found". Esta respuesta 404 también se factura como una solicitud. Al no haber archivos, el costo de almacenamiento es cero, pero los costos de solicitud pueden generar facturas de miles de dólares en una sola noche.
¿Por qué esta estructura?
S3 utiliza recursos del servidor para procesar las solicitudes. Independientemente de si el archivo existe o no, el proceso de recibir la solicitud, verificar los permisos y enviar la respuesta genera costos de computación. Por eso también se cobran los errores 404.
El problema es que cualquiera puede enviar una solicitud si conoce el nombre del bucket. Aunque los nombres de los buckets de S3 son únicos a nivel mundial, el patrón de la URL es predecible:
https://{nombre-del-bucket}.s3.{región}.amazonaws.com/Si el nombre del bucket es predecible, como my-company-assets, un bot puede encontrarlo automáticamente. Si se conoce el nombre, se pueden enviar solicitudes, y los costos de estas se facturan al propietario del bucket.
Cómo prevenirlo
Usar nombres de bucket impredecibles — Incluir cadenas aleatorias como a7f3k9x2-prod-assets en lugar de my-app-prod. Esto dificulta la adivinación.
No codificar el nombre del bucket en el código — Almacenarlo en variables de entorno o en AWS Parameter Store y hacer referencia a él. Si el nombre del bucket queda en el código fuente, existe el riesgo de que se suba a GitHub.
Colocar CloudFront delante — Configurar el acceso únicamente a través de CloudFront (CDN) en lugar de acceder directamente a S3. El bucket de S3 debe permitir solo las solicitudes provenientes de CloudFront y rechazar las demás.
Configurar alertas de costos de solicitud — Establecer un umbral de costo diario en AWS Budgets. Así, podrá recibir una notificación inmediata si se producen solicitudes inusuales.
Bucket con cobro al solicitante (Requester Pays) — Es una opción que factura el costo de la solicitud a quien la realiza. Sin embargo, no es una solución infalible, ya que las solicitudes no autenticadas no están sujetas a esta opción.
Lección más amplia: los costos en la nube son ilimitados
El incidente con S3 ilustra una característica fundamental de los costos en la nube. En un entorno on-premise (servidores propios), si se adquieren 10 servidores, el costo máximo está definido. Sin embargo, en la nube, el cobro es infinito y proporcional al uso.
Lambda, API Gateway y DynamoDB también funcionan con un modelo de facturación basado en solicitudes. Si entra tráfico inusual, la escalabilidad automática aumenta los costos junto con la carga. Esto se conoce como Billing DDoS o Denegación de Servicio Económica (Economic Denial of Service).
Al utilizar la nube, no basta con monitorear si "el servicio funciona correctamente". También es obligatorio monitorear "si el costo está dentro del rango normal".
Puntos clave
S3 tiene costos de solicitud además de los costos de almacenamiento, y las respuestas 404 por archivos inexistentes también se facturan. Si el nombre del bucket se expone, cualquiera puede enviar solicitudes y los costos se facturan al propietario. Las medidas de defensa clave son: mantener el nombre del bucket en privado, colocar CloudFront al frente y configurar alertas de costos.