Les 10 risques de sécurité les plus critiques pour les applications cloud-native et comment les atténuer.
Le Top 10 de Sécurité des Applications Cloud-Native de l'OWASP identifie les risques de sécurité les plus importants pour les applications cloud-native fonctionnant sur des plateformes telles que Kubernetes, Docker et les architectures serverless. Il couvre les erreurs de configuration, les risques de la chaîne d'approvisionnement, la gestion des secrets, et bien plus encore dans l'ensemble de la pile cloud-native.
Les services cloud, conteneurs et orchestrateurs mal configurés sont la principale cause de violations dans les environnements cloud-native. Cela inclut l'exécution de conteneurs en tant que root, l'utilisation de configurations par défaut, l'exposition publique du serveur API Kubernetes et l'absence d'activation de la journalisation d'audit sur les ressources cloud.
Les attaquants peuvent exploiter des erreurs de configuration pour obtenir le contrôle total du cluster, s'échapper des conteneurs, accéder aux services de métadonnées cloud, ou pivoter à travers l'infrastructure. Un seul bucket S3 mal configuré ou un tableau de bord Kubernetes ouvert a conduit à des violations massives de données.
# 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"]
Les applications cloud-native reçoivent des entrées non seulement à partir de requêtes HTTP traditionnelles, mais également à partir d'événements cloud (SQS, Pub/Sub, EventBridge), de déclencheurs serverless et de communications inter-services. Les failles d'injection dans l'un de ces vecteurs peuvent conduire à l'exécution de commandes, à l'exfiltration de données ou à l'escalade de privilèges.
Les fonctions serverless déclenchées par des événements cloud peuvent traiter des données non fiables sans validation, conduisant à l'injection de commandes OS, l'injection NoSQL ou le SSRF piloté par événements. Les attaquants peuvent empoisonner les files de messages ou les bus d'événements pour compromettre les services en aval.
# 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]}')
Les environnements cloud-native impliquent plusieurs couches d'identité : IAM cloud, RBAC Kubernetes, mTLS de service mesh et authentification au niveau de l'application. Des politiques mal configurées ou trop permissives à n'importe quelle couche peuvent permettre des déplacements latéraux, l'escalade de privilèges ou l'accès non autorisé à des ressources sensibles.
Des rôles IAM trop permissifs assignés aux pods peuvent accorder aux charges de travail un accès à l'ensemble du compte cloud. L'absence d'authentification service-à-service permet à n'importe quel pod compromis d'usurper l'identité d'autres services.
# 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"]
Les pipelines CI/CD sont des cibles de grande valeur car ils ont un accès en écriture aux environnements de production. Compromettre un pipeline de build permet des attaques de la chaîne d'approvisionnement, l'injection de code malveillant et le déploiement d'images avec des portes dérobées. Les configurations de pipeline insécurisées, les images de base empoisonnées et les artefacts non signés contribuent tous à ce risque.
Un pipeline CI/CD compromis peut déployer du code malveillant dans tous les environnements, voler des secrets stockés dans les variables du pipeline ou altérer les images de conteneurs. Les attaques de type SolarWinds démontrent l'impact catastrophique d'une compromission de la chaîne d'approvisionnement.
# 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
Les secrets tels que les clés API, les identifiants de base de données et les certificats TLS sont souvent codés en dur dans le code source, stockés dans des ConfigMaps en texte clair ou intégrés dans les images de conteneurs. Les Secrets Kubernetes ne sont encodés qu'en base64 par défaut, non chiffrés, offrant une protection minimale.
Les secrets exposés peuvent donner aux attaquants un accès direct aux bases de données, comptes cloud et services tiers. Les secrets dans l'historique git, les couches de conteneurs ou les variables d'environnement sont facilement découverts et exploités.
# 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
Par défaut, Kubernetes permet à tous les pods de communiquer entre eux sans restriction. Des NetworkPolicies manquantes ou trop permissives, des groupes de sécurité et des règles de pare-feu permettent les déplacements latéraux au sein du cluster et entre les services cloud.
Sans segmentation réseau, un pod compromis peut atteindre n'importe quel autre service dans le cluster, accéder directement aux bases de données ou exfiltrer des données vers des endpoints externes. Les réseaux plats amplifient le rayon de souffle de toute violation.
# 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
Les applications cloud-native s'appuient fortement sur des images de base open-source, des bibliothèques et des opérateurs Kubernetes. L'exécution de composants obsolètes ou non corrigés avec des CVE connus expose l'application à des exploits bien documentés. Les images de conteneurs incluent souvent des centaines de packages, chacun étant une vulnérabilité potentielle.
Les vulnérabilités connues dans les images de base (par exemple, Log4Shell, bugs OpenSSL) peuvent être exploitées à l'aide d'outils accessibles au public. Les attaquants recherchent activement des conteneurs exécutant des versions vulnérables. Une seule bibliothèque non corrigée peut compromettre l'ensemble de la charge de travail.
# 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"]
Les environnements cloud-native facilitent le lancement de ressources mais rendent difficile leur suivi. Les conteneurs orphelins, les namespaces oubliés, les ressources cloud obsolètes et les déploiements informatiques parallèles créent une surface d'attaque non gérée. Sans inventaire d'actifs approprié, les équipes de sécurité ne peuvent pas protéger ce qu'elles ne savent pas exister.
Les ressources oubliées ou non gérées exécutent souvent des logiciels obsolètes, manquent de surveillance de la sécurité et ont des identifiants périmés. Les attaquants ciblent ces actifs négligés comme points d'entrée car ils sont moins susceptibles d'être surveillés ou corrigés.
# 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 } } }
Sans quotas de ressources et limites appropriés, une seule charge de travail défaillante ou compromise peut consommer tout le CPU, la mémoire ou le stockage disponible, provoquant un déni de service pour d'autres applications. Les attaques de cryptojacking sont particulièrement courantes dans les environnements sans limites de ressources.
Les attaquants peuvent déployer des conteneurs de cryptominage ou des charges de travail gourmandes en ressources qui consomment toutes les ressources du cluster. Sans limites, une bombe fork ou une fuite de mémoire dans un pod peut faire planter l'ensemble du nœud, affectant toutes les charges de travail co-localisées.
# 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"
Les environnements cloud-native génèrent des journaux sur plusieurs couches : application, runtime de conteneur, orchestrateur, service mesh et plateforme cloud. Sans journalisation centralisée, corrélation entre ces couches et détection de menaces à l'exécution, les incidents de sécurité passent inaperçus ou sont découverts trop tard.
Les conteneurs éphémères perdent leurs journaux lorsqu'ils sont terminés, détruisant les preuves forensiques. Sans journaux d'audit Kubernetes et surveillance à l'exécution, les attaquants peuvent créer des portes dérobées, escalader les privilèges ou exfiltrer des données sans déclencher d'alertes.
# 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 | Vulnérabilité | Sévérité | Atténuation Clé |
|---|---|---|---|
| CNAS-1 | Configuration Cloud/Conteneur/Orchestration Insécurisée | Critical | Images distroless, Pod Security Standards, analyse IaC |
| CNAS-2 | Failles d'Injection (Événements Cloud) | Critical | Validation d'entrée, SDK plutôt que shell, filtrage de sortie |
| CNAS-3 | Authentification et Autorisation Inappropriées | Critical | RBAC au privilège minimum, IRSA, mTLS |
| CNAS-4 | Failles du Pipeline CI/CD et de la Chaîne d'Approvisionnement | High | SHA épinglés, signature d'images, provenance SLSA |
| CNAS-5 | Stockage Insécurisé des Secrets | Critical | Vault/Secrets Manager, chiffrement KMS, analyse de secrets |
| CNAS-6 | Politiques Réseau Trop Permissives | High | Refus par défaut, restrictions de sortie, Calico/Cilium |
| CNAS-7 | Composants avec Vulnérabilités Connues | High | Analyse d'images, images de base minimales, SBOM |
| CNAS-8 | Gestion Inappropriée des Actifs | Medium | Balisage des ressources, nettoyage automatisé, IaC |
| CNAS-9 | Quotas de Ressources de Calcul Inadéquats | Medium | Limites de ressources, ResourceQuotas, surveillance de l'utilisation |
| CNAS-10 | Journalisation et Surveillance Inefficaces | High | Journaux d'audit, Falco/Sysdig, SIEM centralisé |