Los 10 riesgos de seguridad más críticos para aplicaciones nativas de la nube y cómo mitigarlos.
El OWASP Cloud-Native Application Security Top 10 identifica los riesgos de seguridad más prominentes para aplicaciones nativas de la nube que se ejecutan en plataformas como Kubernetes, Docker y arquitecturas serverless. Cubre configuraciones incorrectas, riesgos de la cadena de suministro, gestión de secretos y más en todo el stack nativo de la nube.
Los servicios en la nube, contenedores y orquestadores mal configurados son la causa principal de brechas en entornos nativos de la nube. Esto incluye ejecutar contenedores como root, usar configuraciones predeterminadas, exponer públicamente el servidor API de Kubernetes y no habilitar el registro de auditoría en recursos de la nube.
Los atacantes pueden explotar configuraciones incorrectas para obtener control total del clúster, escapar de contenedores, acceder a servicios de metadatos de la nube o moverse lateralmente por la infraestructura. Un único bucket S3 mal configurado o un dashboard de Kubernetes abierto ha llevado a brechas masivas de datos.
# Running container as root with no resource limits FROM ubuntu:latest RUN apt-get update && apt-get install -y curl wget COPY app /app # No USER directive Eruns as root! CMD ["/app/server"]
FROM gcr.io/distroless/static:nonroot COPY --chown=65534:65534 app /app USER 65534:65534 EXPOSE 8080 ENTRYPOINT ["/app/server"]
Las aplicaciones nativas de la nube reciben entrada no solo de solicitudes HTTP tradicionales sino también de eventos de la nube (SQS, Pub/Sub, EventBridge), disparadores serverless y comunicación entre servicios. Las fallas de inyección en cualquiera de estos vectores pueden llevar a la ejecución de comandos, exfiltración de datos o escalada de privilegios.
Las funciones serverless activadas por eventos de la nube pueden procesar datos no confiables sin validación, lo que lleva a inyección de comandos del SO, inyección NoSQL o SSRF impulsado por eventos. Los atacantes pueden envenenar colas de mensajes o buses de eventos para comprometer servicios posteriores.
# Lambda function processing S3 event without sanitizing filename import os def handler(event, context): bucket = event['Records'][0]['s3']['bucket']['name'] key = event['Records'][0]['s3']['object']['key'] # Command injection via crafted filename! os.system(f"aws s3 cp s3://{bucket}/{key} /tmp/{key}")
import boto3, re from urllib.parse import unquote_plus def handler(event, context): s3 = boto3.client('s3') bucket = event['Records'][0]['s3']['bucket']['name'] key = unquote_plus(event['Records'][0]['s3']['object']['key']) # Validate key against allowlist pattern if not re.match(r'^[\w\-./]+$', key): raise ValueError(f"Invalid S3 key: {key}") # Use SDK instead of shell commands s3.download_file(bucket, key, f'/tmp/{key.split("/")[-1]}')
Los entornos nativos de la nube involucran múltiples capas de identidad: IAM de la nube, RBAC de Kubernetes, mTLS de service mesh y autenticación a nivel de aplicación. Las políticas mal configuradas o excesivamente permisivas en cualquier capa pueden permitir movimiento lateral, escalada de privilegios o acceso no autorizado a recursos sensibles.
Los roles IAM excesivamente permisivos asignados a pods pueden otorgar a las cargas de trabajo acceso a toda la cuenta de la nube. La falta de autenticación de servicio a servicio permite que cualquier pod comprometido suplante a otros servicios.
# Overly permissive ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: default-admin subjects: - kind: ServiceAccount name: default # Default SA Eshared by all pods! namespace: default roleRef: kind: ClusterRole name: cluster-admin # Full cluster access! apiGroup: rbac.authorization.k8s.io
# Dedicated ServiceAccount with minimal Role apiVersion: v1 kind: ServiceAccount metadata: name: order-service namespace: production annotations: eks.amazonaws.com/role-arn: arn:aws:iam::123456:role/order-svc --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: order-service-role namespace: production rules: - apiGroups: [""] resources: ["configmaps"] verbs: ["get"]
Los pipelines CI/CD son objetivos de alto valor porque tienen acceso de escritura a entornos de producción. Comprometer un pipeline de construcción permite ataques a la cadena de suministro, inyección de código malicioso y despliegue de imágenes con puertas traseras. Las configuraciones inseguras de pipelines, imágenes base envenenadas y artefactos sin firmar contribuyen a este riesgo.
Un pipeline CI/CD comprometido puede desplegar código malicioso en todos los entornos, robar secretos almacenados en variables del pipeline o alterar imágenes de contenedores. Los ataques estilo SolarWinds demuestran el impacto catastrófico del compromiso de la cadena de suministro.
# Insecure CI pipeline Eunpinned actions, no image signing name: Deploy on: push jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@main # Unpinned Ecould be compromised! - run: | docker build -t myapp:latest . docker push myregistry/myapp:latest # No signing! kubectl apply -f deploy.yaml # No admission control!
name: Secure Deploy on: push permissions: id-token: write jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # Pinned SHA - run: | docker build -t myregistry/myapp:${{ github.sha }} . cosign sign myregistry/myapp:${{ github.sha }} # Sign image - run: trivy image myregistry/myapp:${{ github.sha }} --exit-code 1 - run: kubectl apply -f deploy.yaml # Admission controller verifies signatures
Los secretos como claves API, credenciales de bases de datos y certificados TLS a menudo están codificados en el código fuente, almacenados en ConfigMaps de texto plano o integrados en imágenes de contenedores. Los Secrets de Kubernetes solo están codificados en base64 por defecto, no encriptados, proporcionando protección mínima.
Los secretos expuestos pueden dar a los atacantes acceso directo a bases de datos, cuentas de la nube y servicios de terceros. Los secretos en el historial de git, capas de contenedores o variables de entorno se descubren y explotan fácilmente.
# Secrets in plaintext environment variables apiVersion: v1 kind: Pod metadata: name: my-app spec: containers: - name: app env: - name: DB_PASSWORD value: "SuperSecret123!" # Plaintext in manifest! - name: AWS_SECRET_KEY value: "AKIA..." # Cloud credentials in YAML!
# Use External Secrets Operator with a vault backend apiVersion: external-secrets.io/v1beta1 kind: ExternalSecret metadata: name: my-app-secrets spec: refreshInterval: 1h secretStoreRef: name: vault-backend kind: ClusterSecretStore target: name: my-app-secrets data: - secretKey: db-password remoteRef: key: secret/data/myapp property: db-password
Por defecto, Kubernetes permite que todos los pods se comuniquen entre sí sin restricción. Las NetworkPolicies faltantes o excesivamente permisivas, grupos de seguridad y reglas de firewall habilitan el movimiento lateral dentro del clúster y entre servicios de la nube.
Sin segmentación de red, un pod comprometido puede alcanzar cualquier otro servicio en el clúster, acceder directamente a bases de datos o exfiltrar datos a endpoints externos. Las redes planas amplifican el radio de impacto de cualquier brecha.
# No NetworkPolicy Eall pods can talk to everything apiVersion: v1 kind: Namespace metadata: name: production # No NetworkPolicy resources defined # All ingress and egress traffic is allowed by default
# Default-deny all traffic, then allow only what's needed apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny-all namespace: production spec: podSelector: {} policyTypes: ["Ingress", "Egress"] --- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-frontend-to-api namespace: production spec: podSelector: matchLabels: app: api-server ingress: - from: - podSelector: matchLabels: app: frontend ports: - port: 8080
Las aplicaciones nativas de la nube dependen en gran medida de imágenes base de código abierto, bibliotecas y operadores de Kubernetes. Ejecutar componentes desactualizados o sin parches con CVE conocidos expone la aplicación a exploits bien documentados. Las imágenes de contenedores a menudo incluyen cientos de paquetes, cada uno una vulnerabilidad potencial.
Las vulnerabilidades conocidas en imágenes base (por ejemplo, Log4Shell, bugs de OpenSSL) pueden ser explotadas usando herramientas disponibles públicamente. Los atacantes escanean activamente en busca de contenedores que ejecutan versiones vulnerables. Una sola biblioteca sin parchear puede comprometer toda la carga de trabajo.
# Using outdated base image with known CVEs FROM node:14 # EOL version with known vulns COPY package.json . RUN npm install # No audit, no lockfile verification COPY . . CMD ["node", "server.js"]
# Use current, slim base image with vulnerability scanning FROM node:22-slim AS build WORKDIR /app COPY package.json package-lock.json ./ RUN npm ci --only=production # Reproducible install from lockfile RUN npm audit --audit-level=high # Fail on high+ vulns FROM gcr.io/distroless/nodejs22-debian12 COPY --from=build /app /app CMD ["/app/server.js"]
Los entornos nativos de la nube facilitan la creación de recursos pero dificultan su seguimiento. Los contenedores huérfanos, namespaces olvidados, recursos de la nube obsoletos y despliegues de TI en la sombra crean una superficie de ataque no administrada. Sin un inventario adecuado de activos, los equipos de seguridad no pueden proteger lo que no saben que existe.
Los recursos olvidados o no administrados a menudo ejecutan software desactualizado, carecen de monitoreo de seguridad y tienen credenciales obsoletas. Los atacantes apuntan a estos activos descuidados como puntos de entrada porque es menos probable que sean monitoreados o parcheados.
# Resources created without tagging or lifecycle management resource "aws_instance" "test_server" { ami = "ami-0abcdef1234567890" instance_type = "t3.medium" # No tags Ewho owns this? What's it for? # No lifecycle policy Eruns forever } resource "aws_s3_bucket" "temp_data" { bucket = "temp-data-2024" # No expiration, no access logging }
resource "aws_instance" "test_server" { ami = "ami-0abcdef1234567890" instance_type = "t3.medium" tags = { Name = "test-server" Owner = "platform-team" Environment = "staging" ManagedBy = "terraform" ExpiresAt = "2026-04-30" } } resource "aws_s3_bucket" "temp_data" { bucket = "temp-data-2024" tags = { Owner = "data-team" ManagedBy = "terraform" } lifecycle_rule { enabled = true expiration { days = 90 } } }
Sin las cuotas y límites de recursos adecuados, una sola carga de trabajo mal comportada o comprometida puede consumir toda la CPU, memoria o almacenamiento disponible, causando denegación de servicio para otras aplicaciones. Los ataques de criptojacking son particularmente comunes en entornos sin límites de recursos.
Los atacantes pueden desplegar contenedores de criptominería o cargas de trabajo intensivas en recursos que consumen todos los recursos del clúster. Sin límites, una bomba fork o fuga de memoria en un pod puede bloquear todo el nodo, afectando todas las cargas de trabajo co-ubicadas.
# Pod with no resource limits apiVersion: v1 kind: Pod metadata: name: my-app spec: containers: - name: app image: myapp:latest # No resources block Ecan consume unlimited CPU/memory!
apiVersion: v1 kind: Pod metadata: name: my-app spec: containers: - name: app image: myapp:1.2.3 resources: requests: cpu: "100m" memory: "128Mi" limits: cpu: "500m" memory: "512Mi" --- # Namespace-level quota apiVersion: v1 kind: ResourceQuota metadata: name: compute-quota namespace: production spec: hard: requests.cpu: "10" requests.memory: "20Gi" limits.cpu: "20" limits.memory: "40Gi"
Los entornos nativos de la nube generan registros en múltiples capas: aplicación, runtime de contenedores, orquestador, service mesh y plataforma de la nube. Sin registro centralizado, correlación entre estas capas y detección de amenazas en tiempo de ejecución, los incidentes de seguridad pasan desapercibidos o se descubren demasiado tarde.
Los contenedores efímeros pierden sus registros cuando se terminan, destruyendo evidencia forense. Sin registros de auditoría de Kubernetes y monitoreo en tiempo de ejecución, los atacantes pueden crear puertas traseras, escalar privilegios o exfiltrar datos sin activar ninguna alerta.
# No audit policy, no log forwarding apiVersion: v1 kind: Pod metadata: name: my-app spec: containers: - name: app image: myapp:latest # Logs go to stdout only Elost when pod restarts # No audit logging configured on the cluster # No runtime security monitoring
# Kubernetes audit policy for security events apiVersion: audit.k8s.io/v1 kind: Policy rules: - level: RequestResponse resources: - group: "" resources: ["secrets", "configmaps"] - level: Metadata resources: - group: "rbac.authorization.k8s.io" resources: ["clusterroles", "clusterrolebindings"] - level: Metadata verbs: ["create", "delete", "patch"] # Deploy Falco for runtime threat detection # Forward logs to SIEM via Fluent Bit / Fluentd
| ID | Vulnerabilidad | Severidad | Mitigación Clave |
|---|---|---|---|
| CNAS-1 | Configuración Insegura de Nube/Contenedor/Orquestación | Critical | Imágenes distroless, Pod Security Standards, escaneo de IaC |
| CNAS-2 | Fallas de Inyección (Eventos de Nube) | Critical | Validación de entrada, SDK sobre shell, filtrado de salida |
| CNAS-3 | Autenticación y Autorización Inadecuadas | Critical | RBAC de mínimo privilegio, IRSA, mTLS |
| CNAS-4 | Fallas en Pipeline CI/CD y Cadena de Suministro | High | SHAs fijados, firma de imágenes, procedencia SLSA |
| CNAS-5 | Almacenamiento Inseguro de Secretos | Critical | Vault/Secrets Manager, cifrado KMS, escaneo de secretos |
| CNAS-6 | Políticas de Red Excesivamente Permisivas | High | Denegación por defecto, restricciones de salida, Calico/Cilium |
| CNAS-7 | Componentes con Vulnerabilidades Conocidas | High | Escaneo de imágenes, imágenes base mínimas, SBOM |
| CNAS-8 | Gestión de Activos Inadecuada | Medium | Etiquetado de recursos, limpieza automatizada, IaC |
| CNAS-9 | Límites de Cuota de Recursos de Cómputo Inadecuados | Medium | Límites de recursos, ResourceQuotas, monitoreo de uso |
| CNAS-10 | Registro y Monitoreo Ineficaces | High | Registros de auditoría, Falco/Sysdig, SIEM centralizado |