¿Qué es el OWASP Kubernetes Top 10?

El OWASP Kubernetes Top 10 identifica los riesgos de seguridad más significativos en entornos Kubernetes. Kubernetes se ha convertido en el estándar de facto para la orquestación de contenedores, pero su flexibilidad y complejidad introducen numerosos desafíos de seguridad. Esta guía cubre configuraciones incorrectas de cargas de trabajo, problemas de RBAC, gestión de secretos, segmentación de red y más.

1�E�⃣ K01 - Configuraciones Inseguras de Cargas de Trabajo

Critical

Descripción General

Las configuraciones inseguras de cargas de trabajo son el problema de seguridad más común en Kubernetes. Los contenedores que se ejecutan como root, con privilegios excesivos, sistemas de archivos escribibles o sin límites de recursos crean superficies de ataque significativas. Las configuraciones predeterminadas suelen ser inseguras y deben endurecerse explícitamente.

Riesgo

Un contenedor comprometido con privilegios de root y acceso al host puede escapar del sandbox del contenedor, acceder al sistema de archivos del host y pivotar a otras cargas de trabajo. La escalada de privilegios desde un pod mal configurado puede llevar a un compromiso total del clúster.

Ejemplo de Código Vulnerable

YAML (Kubernetes Pod) ❁EBad
apiVersion: v1
kind: Pod
metadata:
  name: insecure-app
spec:
  containers:
  - name: app
    image: myapp:latest          # Mutable tag!
    securityContext:
      privileged: true            # Full host access!
      runAsUser: 0                # Running as root!
    volumeMounts:
    - mountPath: /host
      name: host-fs
  volumes:
  - name: host-fs
    hostPath:
      path: /                    # Entire host filesystem!

Ejemplo de Código Seguro

YAML (Kubernetes Pod) ✁EGood
apiVersion: v1
kind: Pod
metadata:
  name: secure-app
spec:
  securityContext:
    runAsNonRoot: true
    seccompProfile:
      type: RuntimeDefault
  containers:
  - name: app
    image: myapp@sha256:abc123...  # Immutable digest
    securityContext:
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
      runAsUser: 1000
      capabilities:
        drop: ["ALL"]
    resources:
      limits:
        cpu: "500m"
        memory: "256Mi"
      requests:
        cpu: "100m"
        memory: "128Mi"

Lista de Verificación de Mitigación

2�E�⃣ K02 - Configuraciones de Autorización Excesivamente Permisivas

Critical

Descripción General

El RBAC (Control de Acceso Basado en Roles) de Kubernetes es poderoso pero complejo. Los roles excesivamente permisivos  Eespecialmente los enlaces cluster-admin, permisos comodín y privilegios excesivos de cuentas de servicio  Epermiten el acceso no autorizado a recursos del clúster, secretos y cargas de trabajo.

Riesgo

Un atacante que obtiene acceso a una cuenta de servicio con privilegios excesivos puede listar secretos, crear pods privilegiados, modificar despliegues y escalar a cluster-admin. Las reglas RBAC con comodines son el equivalente en Kubernetes de otorgar acceso root.

Ejemplo de Código Vulnerable

YAML (Kubernetes RBAC) ❁EBad
# ClusterRoleBinding granting cluster-admin to a service account
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: app-admin-binding
subjects:
- kind: ServiceAccount
  name: my-app            # App SA with cluster-admin!
  namespace: default
roleRef:
  kind: ClusterRole
  name: cluster-admin      # Full cluster control!
  apiGroup: rbac.authorization.k8s.io

Ejemplo de Código Seguro

YAML (Kubernetes RBAC) ✁EGood
# Scoped Role with minimum required permissions
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: app-role
  namespace: my-app-ns
rules:
- apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["get", "list"]     # Read-only, specific resources
  resourceNames: ["app-config"]  # Named resource only
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: app-role-binding
  namespace: my-app-ns
subjects:
- kind: ServiceAccount
  name: my-app
  namespace: my-app-ns
roleRef:
  kind: Role
  name: app-role
  apiGroup: rbac.authorization.k8s.io

Lista de Verificación de Mitigación

3�E�⃣ K03 - Fallas en la Gestión de Secretos

Critical

Descripción General

Los Secrets de Kubernetes solo están codificados en base64 por defecto, no encriptados. Almacenar datos sensibles (claves API, contraseñas de bases de datos, certificados TLS) en ConfigMaps planos, variables de entorno o Secrets no encriptados los expone a cualquier persona con acceso a la API. Los Secrets también son visibles en etcd si no se habilita el cifrado en reposo.

Riesgo

Los secretos expuestos permiten a los atacantes acceder a bases de datos, cuentas en la nube y servicios externos. Los Secrets almacenados en etcd sin cifrado pueden ser leídos por cualquiera con acceso a etcd. Los secretos en variables de entorno son visibles en las especificaciones de pods y listados de procesos.

Ejemplo de Código Vulnerable

YAML (Kubernetes) ❁EBad
# Secret in plain ConfigMap  Evisible to anyone
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  DB_PASSWORD: "SuperSecret123!"   # Plaintext password!
  API_KEY: "sk-live-abc123xyz"      # API key in ConfigMap!
---
apiVersion: v1
kind: Pod
metadata:
  name: app
spec:
  containers:
  - name: app
    image: myapp:latest
    envFrom:
    - configMapRef:
        name: app-config    # All values as env vars!

Ejemplo de Código Seguro

YAML (Kubernetes + External Secrets) ✁EGood
# Use External Secrets Operator with a vault backend
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: app-secrets
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: vault-backend
    kind: ClusterSecretStore
  target:
    name: app-secrets
  data:
  - secretKey: db-password
    remoteRef:
      key: secret/myapp/db
      property: password
---
apiVersion: v1
kind: Pod
metadata:
  name: app
spec:
  containers:
  - name: app
    image: myapp@sha256:abc123...
    volumeMounts:
    - name: secrets
      mountPath: /etc/secrets
      readOnly: true          # Mount as read-only files
  volumes:
  - name: secrets
    secret:
      secretName: app-secrets

Lista de Verificación de Mitigación

4�E�⃣ K04 - Falta de Aplicación de Políticas a Nivel de Clúster

High

Descripción General

Sin políticas a nivel de clúster, no hay barreras que impidan el despliegue de cargas de trabajo inseguras. Los Pod Security Standards (PSS), controladores de admisión y motores de políticas como OPA Gatekeeper o Kyverno son esenciales para hacer cumplir las líneas base de seguridad en todos los namespaces.

Riesgo

Sin aplicación de políticas, cualquier desarrollador puede desplegar contenedores privilegiados, usar volúmenes hostPath o deshabilitar controles de seguridad. Una sola carga de trabajo mal configurada puede comprometer todo el clúster. La revisión manual no puede escalar para detectar todas las violaciones.

Ejemplo de Código Vulnerable

Bash ❁EBad
#!/bin/bash
# No admission control  Eany pod spec is accepted
# No Pod Security Standards configured

# Anyone can deploy a privileged container
kubectl run hacker-pod --image=alpine \
  --overrides='{"spec":{"containers":[{
    "name":"hack",
    "image":"alpine",
    "securityContext":{"privileged":true},
    "command":["nsenter","--target","1","--mount","--uts","--ipc","--net","--pid","--","bash"]
  }]}}'

# No policy blocks this  Enow has host root access!

Ejemplo de Código Seguro

YAML (Kyverno ClusterPolicy) ✁EGood
# Enforce Pod Security Standards with Kyverno
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: disallow-privileged
spec:
  validationFailureAction: Enforce
  background: true
  rules:
  - name: deny-privileged
    match:
      any:
      - resources:
          kinds: ["Pod"]
    validate:
      message: "Privileged containers are not allowed."
      pattern:
        spec:
          containers:
          - securityContext:
              privileged: "false"
  - name: require-run-as-non-root
    match:
      any:
      - resources:
          kinds: ["Pod"]
    validate:
      message: "Containers must run as non-root."
      pattern:
        spec:
          securityContext:
            runAsNonRoot: true

Lista de Verificación de Mitigación

5�E�⃣ K05 - Falta de Controles de Segmentación de Red

High

Descripción General

Por defecto, todos los pods en un clúster de Kubernetes pueden comunicarse entre sí sin restricciones. Esta arquitectura de red plana significa que un pod comprometido puede alcanzar cualquier otro pod, servicio o incluso el servidor API de Kubernetes. Las NetworkPolicies son esenciales para implementar microsegmentación.

Riesgo

Sin segmentación de red, el movimiento lateral es trivial. Un pod de frontend comprometido puede acceder directamente a bases de datos backend, servicios internos y la API de metadatos (169.254.169.254). Esto viola el principio de privilegio mínimo en la capa de red.

Ejemplo de Código Vulnerable

YAML (Kubernetes) ❁EBad
# No NetworkPolicy  Eall pods can communicate freely
apiVersion: v1
kind: Namespace
metadata:
  name: production
  # No default deny policy
  # No network policies at all
  # Any pod can reach:
  #   - Other pods in any namespace
  #   - Kubernetes API server
  #   - Cloud metadata API (169.254.169.254)
  #   - External internet

Ejemplo de Código Seguro

YAML (Kubernetes NetworkPolicy) ✁EGood
# Default deny all ingress and egress
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: production
spec:
  podSelector: {}
  policyTypes: ["Ingress", "Egress"]
---
# Allow only frontend to backend communication
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend-to-backend
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes: ["Ingress"]
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - port: 8080
      protocol: TCP

Lista de Verificación de Mitigación

6�E�⃣ K06 - Componentes de Kubernetes Excesivamente Expuestos

High

Descripción General

Los componentes del plano de control de Kubernetes (servidor API, etcd, kubelet, dashboard) y los servicios de aplicación pueden quedar expuestos inadvertidamente a Internet o redes no confiables. Los dashboards expuestos, kubelets sin autenticación y servidores API públicamente accesibles son vectores de ataque comunes.

Riesgo

Los componentes de Kubernetes expuestos proporcionan acceso directo a la gestión del clúster. Una API de kubelet sin autenticación permite la ejecución de contenedores. Un dashboard expuesto con credenciales predeterminadas otorga acceso de cluster-admin. El acceso público a etcd expone todos los datos del clúster, incluidos los secretos.

Ejemplo de Código Vulnerable

YAML (Kubernetes Service) ❁EBad
# Kubernetes Dashboard exposed via LoadBalancer
apiVersion: v1
kind: Service
metadata:
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  type: LoadBalancer        # Public internet access!
  ports:
  - port: 443
    targetPort: 8443
  selector:
    k8s-app: kubernetes-dashboard
# Dashboard bound to cluster-admin service account
# No authentication required  Efull cluster access!

Ejemplo de Código Seguro

YAML (Kubernetes) ✁EGood
# Dashboard accessible only via kubectl proxy
apiVersion: v1
kind: Service
metadata:
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  type: ClusterIP           # Internal only
  ports:
  - port: 443
    targetPort: 8443
  selector:
    k8s-app: kubernetes-dashboard
---
# Access via: kubectl proxy, then browse to:
# http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/
# Or use kubectl port-forward for secure access

Lista de Verificación de Mitigación

7�E�⃣ K07 - Componentes del Clúster Mal Configurados y Vulnerables

High

Descripción General

Los clústeres de Kubernetes constan de muchos componentes: servidor API, etcd, kubelet, kube-proxy, CoreDNS y complementos de terceros (controladores Ingress, service meshes, monitoreo). Los componentes mal configurados o sin parches introducen vulnerabilidades. Las configuraciones predeterminadas a menudo no están endurecidas.

Riesgo

Los componentes vulnerables del clúster pueden ser explotados para ejecución remota de código, escalada de privilegios o denegación de servicio. Los CVEs en kubelet, controladores Ingress o plugins CNI pueden llevar a escapes de contenedores y toma del clúster. Los componentes desactualizados acumulan vulnerabilidades conocidas.

Ejemplo de Código Vulnerable

YAML (Kubernetes) ❁EBad
# kubelet with insecure configuration
# /var/lib/kubelet/config.yaml
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
authentication:
  anonymous:
    enabled: true              # Anyone can access kubelet API!
  webhook:
    enabled: false             # No authorization!
authorization:
  mode: AlwaysAllow            # All requests permitted!
readOnlyPort: 10255            # Unauthenticated read port open!

Ejemplo de Código Seguro

YAML (Kubernetes) ✁EGood
# Hardened kubelet configuration
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
authentication:
  anonymous:
    enabled: false             # Deny anonymous access
  webhook:
    enabled: true              # Use API server for auth
  x509:
    clientCAFile: /etc/kubernetes/pki/ca.crt
authorization:
  mode: Webhook                # API server authorizes requests
readOnlyPort: 0                # Disable read-only port
protectKernelDefaults: true
eventRecordQPS: 5

Lista de Verificación de Mitigación

8�E�⃣ K08 - Movimiento Lateral del Clúster a la Nube

Critical

Descripción General

Los clústeres de Kubernetes que se ejecutan en entornos de nube (AWS, GCP, Azure) pueden acceder a las APIs de metadatos de la nube y roles IAM adjuntos a los nodos. Los atacantes que comprometen un pod pueden usarlos para escalar privilegios desde el clúster a la cuenta de la nube, accediendo a buckets S3, bases de datos y otros servicios en la nube.

Riesgo

Los roles IAM a nivel de nodo son heredados por todos los pods en ese nodo. Un pod comprometido puede consultar la API de metadatos (169.254.169.254) para obtener credenciales de la nube y luego acceder a cualquier recurso en la nube que el rol del nodo permita. Esto habilita el movimiento lateral desde Kubernetes al entorno de nube más amplio.

Ejemplo de Código Vulnerable

Terraform (AWS EKS) ❁EBad
# Node IAM role with excessive permissions
resource "aws_iam_role_policy_attachment" "node_admin" {
  role       = aws_iam_role.node_role.name
  policy_arn = "arn:aws:iam::aws:policy/AdministratorAccess"
  # All pods on this node inherit admin access!
}

# No IMDS restrictions  Eany pod can get node credentials
# curl http://169.254.169.254/latest/meta-data/iam/security-credentials/

Ejemplo de Código Seguro

Terraform (AWS EKS with IRSA) ✁EGood
# Use IAM Roles for Service Accounts (IRSA)
resource "aws_iam_role" "app_role" {
  name = "my-app-role"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Effect = "Allow"
      Principal = {
        Federated = aws_iam_openid_connect_provider.eks.arn
      }
      Action = "sts:AssumeRoleWithWebIdentity"
      Condition = {
        StringEquals = {
          "${aws_iam_openid_connect_provider.eks.url}:sub" =
            "system:serviceaccount:my-ns:my-app"
        }
      }
    }]
  })
}

# Pod-level scoped IAM via service account annotation
# Only this specific pod gets these specific permissions

Lista de Verificación de Mitigación

9�E�⃣ K09 - Mecanismos de Autenticación Rotos

Critical

Descripción General

Kubernetes soporta múltiples mecanismos de autenticación: certificados, tokens, OIDC y autenticación webhook. La autenticación rota incluye el uso de tokens estáticos, compartir archivos kubeconfig, no rotar certificados y no integrar con proveedores de identidad. El montaje automático de tokens de cuenta de servicio crea una superficie de ataque innecesaria.

Riesgo

Los archivos kubeconfig y tokens de cuenta de servicio robados o filtrados proporcionan acceso directo al clúster. Los tokens estáticos que nunca expiran otorgan acceso persistente. Sin gestión centralizada de identidad, revocar el acceso a miembros del equipo que se fueron es difícil y propenso a errores.

Ejemplo de Código Vulnerable

YAML (Kubernetes) ❁EBad
# Static token file for API server authentication
# /etc/kubernetes/token-auth-file.csv
# token,user,uid,"groups"
# abc123,admin,1,"system:masters"  # Static token, never expires!

# Pod with auto-mounted service account token
apiVersion: v1
kind: Pod
metadata:
  name: app
spec:
  # automountServiceAccountToken defaults to true!
  # Token mounted at /var/run/secrets/kubernetes.io/serviceaccount/token
  containers:
  - name: app
    image: myapp:latest
    # App doesn't need K8s API access but has a token anyway

Ejemplo de Código Seguro

YAML (Kubernetes) ✁EGood
# Disable auto-mounted token for pods that don't need API access
apiVersion: v1
kind: ServiceAccount
metadata:
  name: my-app
  namespace: my-app-ns
automountServiceAccountToken: false  # No auto-mount
---
# For pods that need API access, use bound tokens with expiry
apiVersion: v1
kind: Pod
metadata:
  name: api-consumer
spec:
  serviceAccountName: api-consumer-sa
  automountServiceAccountToken: false
  containers:
  - name: app
    image: myapp@sha256:abc123...
    volumeMounts:
    - name: token
      mountPath: /var/run/secrets/tokens
      readOnly: true
  volumes:
  - name: token
    projected:
      sources:
      - serviceAccountToken:
          expirationSeconds: 3600  # 1-hour expiry
          audience: api-server

Lista de Verificación de Mitigación

🔟 K10 - Registro y Monitoreo Inadecuados

Medium

Descripción General

Kubernetes genera eventos de auditoría para solicitudes al servidor API, pero el registro de auditoría a menudo está deshabilitado o mal configurado. Sin un registro y monitoreo adecuados, las actividades maliciosas  Ecomo el acceso no autorizado a secretos, cambios en RBAC y escapes de contenedores  Epasan desapercibidas. El monitoreo de seguridad en tiempo de ejecución a nivel de contenedor y nodo es esencial.

Riesgo

Sin registro de auditoría, los atacantes operan sin ser detectados. Pueden crear cuentas de servicio de puerta trasera, extraer secretos y modificar cargas de trabajo sin ningún registro. La respuesta a incidentes se ve gravemente afectada cuando no hay un rastro de auditoría para determinar qué sucedió, cuándo y por quién.

Ejemplo de Código Vulnerable

YAML (Kubernetes) ❁EBad
# API server with no audit logging configured
# kube-apiserver flags:
#   --audit-log-path=""           # No audit log!
#   --audit-policy-file=""        # No audit policy!

# No runtime security monitoring
# No alerting on suspicious activities
# Container logs not collected centrally
# Default log retention  Elogs lost on pod restart

Ejemplo de Código Seguro

YAML (Kubernetes Audit Policy) ✁EGood
# Comprehensive audit policy
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
# Log all secret access at Metadata level
- level: Metadata
  resources:
  - group: ""
    resources: ["secrets"]
# Log RBAC changes at RequestResponse level
- level: RequestResponse
  resources:
  - group: rbac.authorization.k8s.io
    resources: ["clusterroles", "clusterrolebindings", "roles", "rolebindings"]
# Log pod exec/attach (potential attacks)
- level: Request
  resources:
  - group: ""
    resources: ["pods/exec", "pods/attach", "pods/portforward"]
# Default: log at Metadata level
- level: Metadata

Lista de Verificación de Mitigación

📊 Tabla Resumen

ID Vulnerabilidad Severidad Mitigación Clave
K01Configuraciones Inseguras de Cargas de TrabajoCriticalNo-root, FS de solo lectura, eliminar capacidades, límites de recursos
K02Autorización Excesivamente PermisivaCriticalRBAC con alcance de namespace, sin comodines, auditar enlaces
K03Fallas en la Gestión de SecretosCriticalSecretos externos, cifrado en reposo, montajes de archivos
K04Falta de Aplicación de PolíticasHighPod Security Standards, Kyverno/OPA Gatekeeper
K05Falta de Segmentación de RedHighNetworkPolicies de denegación por defecto, microsegmentación
K06Componentes Excesivamente ExpuestosHighServicios ClusterIP, kubectl proxy, reglas de firewall
K07Componentes del Clúster Mal ConfiguradosHighCIS Benchmark, deshabilitar auth anónima, gestión de parches
K08Movimiento Lateral del Clúster a la NubeCriticalIRSA/Workload Identity, bloquear API de metadatos, IMDSv2
K09Mecanismos de Autenticación RotosCriticalIntegración OIDC, tokens vinculados, deshabilitar auto-montaje
K10Registro y Monitoreo InadecuadosMediumRegistro de auditoría, Falco/Tetragon, integración SIEM