Uno de los mitos más peligrosos en la ingeniería de software moderna es asumir que, al delegar los servidores físicos al proveedor cloud, la seguridad de la aplicación queda resuelta de forma automática. Aunque AWS administra la seguridad del hipervisor, las instalaciones físicas y los parches de kernel bajo el Modelo de Responsabilidad Compartida de AWS, la seguridad de la capa de aplicación, la lógica de autorización, los roles IAM y el perímetro de red siguen siendo 100% responsabilidad de tu equipo.
En una arquitectura Serverless orientada a eventos, el perímetro de red tradicional (bastiones, firewalls de subred privada, inspección física de paquetes) desaparece. Las funciones Lambda se exponen a invocaciones directas desde API Gateways, colas SQS, buckets S3 y webhooks externos. Sin un enfoque estricto de Zero Trust, defensa perimetral con AWS WAF y políticas de mínimo privilegio en IAM, una startup puede ser víctima de Denegación de Billetera (Denial of Wallet), inyecciones de eventos o filtraciones masivas de datos mediante autorizaciones defectuosas a nivel de objeto (BOLA).
💡 Resumen Ejecutivo: Blindar APIs Serverless exige inspección perimetral con AWS WAF para bloquear ataques de Denegación de Billetera (DoW), roles IAM de mínimo privilegio acotados por ARN y validación estricta en memoria con esquemas Zod antes de procesar cualquier evento.
1. Vectores de Amenaza Específicos de Serverless (OWASP)
A diferencia de los servidores monolíticos tradicionales donde un atacante busca ganar acceso de shell o comprometer el sistema operativo base, los vectores de ataque en Serverless explotan la naturaleza elástica y desacoplada de la infraestructura:
| Vector de Amenaza Serverless | Mecanismo de Ataque | Impacto en el Negocio | Estrategia de Mitigación Primaria |
|---|---|---|---|
| Denegación de Billetera (DoW) | Saturar endpoints con millones de solicitudes automatizadas para inflar ejecuciones Lambda. | Quiebra financiera o factura cloud de miles de dólares sin caída del servicio. | Reglas de rate-limiting en AWS WAF + cuotas de concurrencia en API Gateway. |
| Inyección en Fuentes de Eventos | Enviar payloads maliciosos a través de colas SQS, metadatos en S3 o parámetros no filtrados. | Inyección NoSQL en DynamoDB o ejecución arbitraria dentro del runtime de Lambda. | Validación de esquemas con Zod en la entrada; jamás confiar en el evento crudo. |
| Roles IAM Sobredimensionados | Asignar permisos comodín (Action: "*", Resource: "*") a las funciones Lambda. | Movimiento lateral y toma de control total de la cuenta de AWS tras explotar una librería. | Acotar políticas IAM al ARN exacto de la tabla, cola o bucket específico. |
| Broken Object-Level Auth (BOLA) | Manipular identificadores en URIs (/pedidos/{pedidoId}) para acceder a datos de otros clientes. | Fuga crítica de privacidad de usuarios y sanciones regulatorias severas. | Validación en código vinculando el sub del token JWT con la clave del ítem en base de datos. |
| Secretos en Variables de Entorno | Almacenar tokens de Stripe o contraseñas en variables de entorno de Lambda en texto plano. | Fuga de credenciales en volcados de logs de CloudWatch o paneles de observabilidad. | Consumo dinámico en memoria con AWS Secrets Manager o Parameter Store. |
2. Defensa Perimetral: Arquitectura con AWS WAF y API Gateway
El principio fundamental de una arquitectura segura y costo-eficiente es bloquear el tráfico malicioso en el borde de la red (Edge) antes de que consuma un solo milisegundo de cómputo en AWS Lambda:
flowchart LR
A[Petición del Cliente] --> B[AWS WAF WebACL]
B -- Bloqueo 403 --> C[Rate Limit Superado / Inyección SQL Detectada]
B -- Permitido --> D[Amazon API Gateway]
D --> E[Lambda Authorizer / JWT Validado]
E --> F[Función Lambda de Negocio]
F --> G[(Amazon DynamoDB)]
Reglas Esenciales de AWS WAF para APIs Serverless
- Protección Anti-DDoS y DoW basada en Tasa (Rate-Based Rule): Configurar una regla que limite las solicitudes procedentes de una misma dirección IP a un máximo de 2,000 peticiones por ventana móvil de 5 minutos. Si un bot intenta saturar un endpoint de cálculo intensivo, el WAF corta la conexión en la capa perimetral con un HTTP 403 Forbidden.
- AWS Managed Rules Common Rule Set (CRS): Inspección automatizada que filtra ataques comunes de la web, incluyendo inyecciones de comandos en el sistema operativo, evasiones de directorios y anomalías en headers HTTP.
- Reglas contra Inyecciones SQL y Entradas Maliciosas: Analiza cuerpos de peticiones JSON y parámetros de consulta buscando patrones de inyección antes de que el payload sea procesado por la aplicación.
- Reputación de IPs y Bloqueo de Proxies Anónimos: Deniega automáticamente el acceso a rangos de direcciones IP catalogados por Amazon Threat Intelligence como proxies anónimos, nodos de salida de Tor o centros de comando de botnets.
3. Implementación de Infraestructura Segura con AWS CDK (TypeScript)
La seguridad jamás debe depender de configuraciones manuales en la consola de AWS. Debe declararse de forma inmutable a través de Infrastructure as Code (IaC):
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as apigateway from 'aws-cdk-lib/aws-apigateway';
import * as wafv2 from 'aws-cdk-lib/aws-wafv2';
import * as iam from 'aws-cdk-lib/aws-iam';
import * as path from 'path';
export class SeguridadServerlessStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// 1. Rol de Ejecución IAM de Mínimo Privilegio (Sin Comodines)
const lambdaRole = new iam.Role(this, 'LambdaSeguroExecutionRole', {
assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
description: 'Rol de ejecución con permisos estrictamente acotados',
});
// Permisos de CloudWatch acotados exclusivamente a su propio grupo de logs
lambdaRole.addToPolicy(
new iam.PolicyStatement({
actions: ['logs:CreateLogGroup', 'logs:CreateLogStream', 'logs:PutLogEvents'],
resources: [`arn:aws:logs:${this.region}:${this.account}:log-group:/aws/lambda/ApiSeguraHandler:*`],
})
);
// Permisos de DynamoDB acotados al ARN de la tabla exacta
lambdaRole.addToPolicy(
new iam.PolicyStatement({
actions: ['dynamodb:GetItem', 'dynamodb:PutItem', 'dynamodb:UpdateItem'],
resources: [`arn:aws:dynamodb:${this.region}:${this.account}:table/TijikiOperacionesSeguras`],
})
);
// 2. Función Lambda con trazabilidad activa
const apiFunction = new lambda.Function(this, 'ApiSeguraFunction', {
functionName: 'ApiSeguraHandler',
runtime: lambda.Runtime.NODEJS_20_X,
handler: 'index.handler',
code: lambda.Code.fromAsset(path.join(__dirname, '../dist')),
role: lambdaRole,
memorySize: 1024,
timeout: cdk.Duration.seconds(10),
tracing: lambda.Tracing.ACTIVE, // AWS X-Ray
});
// 3. API Gateway REST API con stage de producción
const api = new apigateway.RestApi(this, 'ApiGatewaySeguro', {
restApiName: 'ApiGatewayServerlessSeguro',
deployOptions: {
stageName: 'prod',
tracingEnabled: true,
},
});
const integration = new apigateway.LambdaIntegration(apiFunction);
api.root.addResource('transacciones').addMethod('POST', integration);
// 4. AWS WAF WebACL con Rate-Limiting Anti-DoW
const webAcl = new wafv2.CfnWebACL(this, 'ServerlessWebAcl', {
defaultAction: { allow: {} },
scope: 'REGIONAL',
visibilityConfig: {
cloudWatchMetricsEnabled: true,
metricName: 'ServerlessWebAclMetrics',
sampledRequestsEnabled: true,
},
rules: [
{
name: 'RateLimitAntiDoW',
priority: 1,
action: { block: {} },
statement: {
rateBasedStatement: {
limit: 2000,
aggregateKeyType: 'IP',
},
},
visibilityConfig: {
cloudWatchMetricsEnabled: true,
metricName: 'RateLimitAntiDoWMetric',
sampledRequestsEnabled: true,
},
},
{
name: 'AWSManagedRulesCommonRuleSet',
priority: 2,
overrideAction: { none: {} },
statement: {
managedRuleGroupStatement: {
vendorName: 'AWS',
name: 'AWSManagedRulesCommonRuleSet',
},
},
visibilityConfig: {
cloudWatchMetricsEnabled: true,
metricName: 'CommonRulesMetric',
sampledRequestsEnabled: true,
},
},
],
});
// 5. Asociación de WAF al Stage de API Gateway
const stageArn = `arn:aws:apigateway:${this.region}::/restapis/${api.restApiId}/stages/prod`;
new wafv2.CfnWebACLAssociation(this, 'WafAssociation', {
resourceArn: stageArn,
webAclArn: webAcl.attrArn,
});
}
}
4. Análisis FinOps: El Retorno de Inversión (ROI) de AWS WAF
Muchos directores técnicos evitan implementar AWS WAF por percibirlo como un costo fijo adicional. Analicemos el balance financiero real:
Costo Operativo de AWS WAF
- Costo Base del WebACL: $5.00 USD / mes.
- Costo por Regla: 2 reglas administradas + 1 regla rate-based = 3 reglas × $1.00 = $3.00 USD / mes.
- Procesamiento de Solicitudes: $0.60 USD por cada 1,000,000 de peticiones.
- Factura mensual típica para 10M peticiones: $5 + $3 + (10 × $0.60) = ~$14.00 USD / mes.
El Costo de un Ataque de Denegación de Billetera sin WAF
Supongamos un bot malicioso atacando un endpoint público de cálculo o búsqueda que no tiene WAF:
- Volumen del ataque: 1,000 peticiones por segundo durante un fin de semana (48 horas) = 172,800,000 ejecuciones.
- Costo computacional de Lambda (1024 MB @ 200ms): ~$570.00 USD.
- Costo de ingress en API Gateway: ~$172.00 USD.
- Costo de lecturas en DynamoDB o servicios downstream: Miles de dólares adicionales.
Conclusión del Arquitecto: Invertir $14.00 USD al mes en AWS WAF es el seguro operativo más rentable que una empresa de software puede contratar.
5. Antipatrones Críticos y Errores de Seguridad Comunes
1. El Peligro del Comodín Resource: "*" en IAM
Asignar políticas de IAM permisivas para evitar errores durante el desarrollo local.
- La Falla: Si una librería npm de terceros sufre un ataque de cadena de suministro (supply chain attack), el código inyectado tiene permisos para leer todos los buckets S3 de la cuenta o eliminar tablas de DynamoDB.
- La Solución: Restringir cada acción (
PutItem,GetObject) al ARN exacto del recurso que la función necesita acceder.
2. Confiar en la Autenticación del Perímetro sin Validar BOLA en Código
Asumir que, porque la petición pasó por un Authorizer Cognito, el usuario tiene derecho a consultar cualquier registro.
- La Falla: Un usuario autenticado con ID
user_123solicita/api/v1/facturas/factura_999perteneciente a otra empresa y el sistema la devuelve. - La Solución: Todo handler debe verificar en tiempo de ejecución que el identificador del usuario extraído de los claims criptográficos del JWT coincida con el propietario del recurso solicitado.
Preguntas Frecuentes (FAQ)
¿AWS WAF agrega latencia perceptible a las APIs?
No. El procesamiento de inspección en AWS WAF añade típicamente entre 0.5 ms y 2 ms de latencia, lo cual es completamente imperceptible para aplicaciones web y móviles.
¿Se puede utilizar AWS WAF con HTTP APIs de API Gateway?
No de forma directa. AWS WAF se asocia nativamente con REST APIs de API Gateway o distribuciones de Amazon CloudFront. Para proteger HTTP APIs más económicas con WAF, se debe colocar CloudFront frente a la API Gateway.
¿Cómo se protegen los secretos de base de datos en Lambda?
Utilizando la extensión oficial de AWS Parameters and Secrets Lambda Extension, la cual almacena en caché en la memoria local de la microVM los secretos recuperados de AWS Secrets Manager, rotándolos automáticamente sin consultar la API en cada petición.
Conclusión y Auditoría de Seguridad Cloud
La seguridad en la nube no se logra con parches superficiales, sino asumiendo brechas en cada frontera del sistema. Al combinar la defensa perimetral de AWS WAF, roles IAM acotados y validación estricta de contratos en código, tu empresa garantiza la integridad de sus datos y protege su rentabilidad ante cualquier ataque.
🛠️ ¿Dudas sobre la seguridad de tus APIs Serverless o tu infraestructura en AWS?
En Tijiki realizamos auditorías de seguridad cloud, blindamos arquitecturas serverless con AWS WAF y eliminamos riesgos de acceso y denegación de billetera.
👉 Agendar Sesión de Diagnóstico de Arquitectura (30 min con un Arquitecto Senior)