Serverless suele venderse internamente como “menos superficie de ataque” porque no hay que parchear sistemas operativos ni operar máquinas. Eso es parcialmente cierto, pero suele llevar a una consecuencia peligrosa: asumir que el riesgo desaparece. En la práctica, lo que cambia es el tipo de exposición y el punto donde se concentra el control: identidades, eventos, dependencias, secretos y configuración del plano de control.
En empresas con presión por entregar, lo que más se repite no es un exploit sofisticado, sino configuraciones “temporales” que se quedan para siempre: funciones con permisos amplios para desbloquear un sprint, triggers abiertos “solo para pruebas”, secretos en variables de entorno y paquetes NPM/PyPI sin gobernanza. Ese es el caldo de cultivo de la falsa sensación de seguridad.
Mito: “No gestiono servidores, así que no hay riesgo significativo”
Eliminar servidores reduce una clase de problemas (hardening del host, parches del SO, agentes, etc.), pero el riesgo se desplaza a lo que tú sí controlas: IAM/roles, configuración de invocación, red, logs, dependencias y secretos. En serverless, un error de autorización o un secreto expuesto suele tener impacto inmediato porque la función ya está conectada a datos y servicios críticos.
En producción se ve un patrón: como “es solo una función”, se relaja el rigor que sí se aplicaría a un servidor. Resultado típico: una Lambda con un rol que incluye permisos de lectura/escritura sobre múltiples buckets y tablas “porque varias rutas del API lo necesitan”. Cuando esa función se ve comprometida (por una dependencia o un fallo lógico), el atacante no necesita moverse lateralmente por red: el movimiento lateral ocurre vía APIs cloud, usando tus permisos.
Consecuencia en entornos corporativos: el incidente no se manifiesta como caída del servicio, sino como acceso indebido a datos, creación de recursos para persistencia o extracción silenciosa de información. Y el postmortem se complica porque el control está distribuido entre servicio gestionado, permisos y eventos.
Permisos excesivos y abuso de roles: el “root” moderno de serverless
La mayoría de compromisos efectivos en serverless no empiezan con RCE; empiezan con autorización demasiado amplia. En AWS, el rol de ejecución de Lambda; en Azure, la identidad administrada de la Function App; en GCP, la service account asociada a la Cloud Function. Si esa identidad puede leer secretos, enumerar recursos o escribir en storage, el atacante ya tiene un camino claro de pivot.
Un error frecuente en AWS es permitir acciones amplias por comodidad: "Action": "s3:*" sobre "Resource": "*", o permisos de secretsmanager:GetSecretValue para “cualquier secreto” porque la función necesita uno. En Azure, asignar Contributor al resource group a la identidad administrada para evitar tickets de permisos. En GCP, usar una service account con Editor por rapidez. En los tres casos, el impacto deja de ser “una función” y pasa a ser “una porción grande del entorno”.
Cómo se pivota desde una función comprometida: si el atacante logra ejecutar código (por una dependencia vulnerable, una deserialización insegura o una ruta lógica que evalúa entradas), lo siguiente suele ser llamar al plano de control con las credenciales ya presentes en el runtime. Por ejemplo: listar secretos, leer configuraciones, descargar datos de storage, o incluso modificar la propia función para persistir (subir nuevo código, cambiar variables, añadir triggers). No es teoría: es el recorrido natural cuando la identidad de la función es demasiado potente.
- AWS: con permisos de
lambda:UpdateFunctionConfigurationolambda:UpdateFunctionCode, el atacante puede reescribir la función para persistencia; coniam:PassRole, puede lanzar recursos con roles más privilegiados.
En empresa esto se traduce en un incidente que “se arregla” volviendo a desplegar, pero reaparece porque la persistencia quedó en la propia configuración o en permisos delegados. La investigación suele descubrir que el rol de la función tenía más permisos de los que el equipo creía.
- Azure: una identidad con Contributor puede modificar app settings, conexiones y despliegues; si además tiene acceso a Key Vault, el salto a otros sistemas (DBs, colas, APIs internas) es directo.
La lección operativa es que el rol/identidad de una función debe tratarse como una credencial de alto valor, aunque el runtime sea gestionado.
Endpoints expuestos y event injection: cuando el trigger es el vector
Serverless vive de eventos: HTTP, colas, topics, storage, schedulers. La falsa seguridad aparece cuando se asume que “si está detrás de API Gateway” o “si es un trigger gestionado” ya está protegido. En la práctica, el vector suele ser el trigger mal autenticado o mal validado, no la infraestructura.
Ejemplo común en AWS: una Lambda expuesta vía API Gateway con autorización en modo NONE porque “lo pondremos con Cognito después”. En Azure: Functions con Authorization level en Anonymous o claves compartidas filtradas en repositorios o pipelines. En GCP: Cloud Functions con invocación pública habilitada por conveniencia. Ese endpoint “temporal” termina indexado, escaneado o compartido fuera del perímetro y se convierte en puerta de entrada estable.
- Event injection: cuando una función procesa mensajes de una cola/topic sin validar su origen o esquema, un atacante que logre publicar en ese canal (por permisos mal asignados o integraciones externas) puede inyectar eventos maliciosos.
En producción se ve como trabajos que “de repente” ejecutan rutas inesperadas: payloads que disparan reintentos, inflan costes, fuerzan parsing extremo o provocan que se llamen APIs internas con parámetros manipulados. El impacto no es solo seguridad: también disponibilidad y facturación.
- Consecuencia típica: una función que asume que el evento viene de un productor “confiable” y usa campos del mensaje para construir rutas S3/Blob/GCS o consultas a base de datos; un evento inyectado convierte eso en exfiltración o borrado si además hay permisos amplios.
El patrón corporativo que agrava esto es la falta de contratos de evento (esquemas versionados, validación estricta, control de publicadores) y la tendencia a reutilizar la misma cola/topic para múltiples propósitos “para ahorrar”.
Dependencias vulnerables y secretos mal gestionados: el golpe silencioso
En serverless, el ciclo de despliegue suele ser rápido y automatizado, pero eso no garantiza que se controle lo que entra al paquete. Dependencias con vulnerabilidades conocidas, typosquatting o paquetes abandonados son una vía frecuente para ganar ejecución dentro del runtime. El problema se amplifica cuando se empaqueta “lo mínimo viable” sin SBOM, sin pinning de versiones y sin escaneo efectivo en CI.
La otra cara es la gestión de secretos. Es habitual ver credenciales en variables de entorno, en archivos de configuración dentro del ZIP, o inyectadas por pipelines sin controles. Incluso cuando se usa un gestor (AWS Secrets Manager, Azure Key Vault, GCP Secret Manager), se comete el error de dar acceso de lectura a “todos los secretos del proyecto” porque “así no fallará en runtime”. Una vez dentro de la función, extraer secretos suele ser trivial.
Cómo hacerlo en la práctica: configura permisos mínimos y valida que realmente se cumplen con revisiones concretas del plano de control. Por ejemplo, en AWS, evita políticas comodín y limita recursos; una política de ejecución debería parecerse más a esto que a un * generalizado:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["secretsmanager:GetSecretValue"],
"Resource": ["arn:aws:secretsmanager:REGION:ACCOUNT:secret:prod/app/db-*" ]
},
{
"Effect": "Allow",
"Action": ["s3:GetObject"],
"Resource": ["arn:aws:s3:::mi-bucket-prod/prefix-especifico/*"]
}
]
}
Luego valida que no hay privilegios inesperados revisando el rol en IAM (políticas adjuntas y en línea), y utilizando herramientas de análisis de permisos (por ejemplo, el análisis de acceso en IAM) para detectar acciones no utilizadas o rutas de escalada como iam:PassRole. En Azure y GCP, el equivalente operativo es revisar asignaciones RBAC/roles a la identidad administrada o service account, y confirmar que el secreto está acotado por recurso y no por proyecto completo.
Errores comunes en producción en AWS, Azure y GCP que alimentan la falsa seguridad
El problema no es “serverless”, sino cómo se opera bajo presión. En AWS se repite el rol reutilizado entre funciones: un único rol “lambda-execution-prod” con permisos acumulativos para múltiples servicios. En Azure, una Function App que agrupa muchas funciones con una identidad única y, por tanto, un conjunto de permisos que crece sin control. En GCP, una service account compartida por varias Cloud Functions “para simplificar”. Es cómodo, pero convierte cualquier fallo en un incidente transversal.
Otro error recurrente es confiar en controles perimetrales que no existen de forma natural en serverless. Un endpoint HTTP público con validación débil, combinado con permisos amplios, es suficiente para un incidente serio sin necesidad de explotar infraestructura. También se ve mucho el logging incompleto: trazas que no incluyen identidad, origen del evento o contexto suficiente para investigar, y retención insuficiente para correlación.
Ejemplos prácticos que aparecen en auditorías internas:
- AWS Lambda: funciones con acceso a VPC “por defecto” sin necesidad real, que complican visibilidad y hacen que se ignoren alertas; o funciones sin límites de concurrencia donde un abuso del endpoint se convierte en degradación y coste.
El efecto empresarial suele ser doble: por un lado, seguridad (exfiltración o modificación no autorizada); por otro, operación (picos de coste y saturación de sistemas downstream como bases de datos).
- Azure Functions / GCP Cloud Functions: exposición accidental por configuración de invocación pública o keys compartidas; y permisos heredados a nivel de grupo/proyecto que permiten leer secretos o escribir en storage sin que el equipo de aplicación sea consciente.
Cuando esto ocurre, la conversación interna suele quedarse en “cerrar el endpoint” o “rotar el secreto”, pero el problema real era la ausencia de guardrails: identidades sobredimensionadas y falta de validación de eventos.
Recomendaciones para entornos corporativos
La falsa sensación de seguridad en serverless nace de confundir “no administro servidores” con “no tengo superficie de ataque”. En realidad, el riesgo se concentra en identidades (roles/service accounts), triggers (HTTP/eventos) y cadena de suministro (dependencias/secretos). Un compromiso de una función con permisos amplios permite pivotar vía APIs cloud y escalar el impacto sin moverse por red tradicional.
Como recomendaciones realistas en empresa, el enfoque más efectivo suele ser: reducir privilegios de forma tangible (roles por función o por conjunto muy acotado), bloquear invocación pública no justificada y exigir autenticación robusta en endpoints, validar esquema y origen de eventos antes de procesarlos, y endurecer la gestión de secretos (acotados por recurso y con rotación). Complementa esto con validaciones operativas: revisar asignaciones RBAC/IAM, detectar políticas comodín, y asegurar logging suficiente para investigar.
Si tu equipo solo puede hacer una cosa esta semana, que sea revisar la identidad de ejecución de cada función crítica y eliminar permisos “por si acaso”. En serverless, ese “por si acaso” suele ser el incidente de mañana.
¿Te interesa la seguridad en Cloud?
Comparto análisis técnicos, laboratorios prácticos y experiencias reales sobre Cloud Security.