
Riproduce CVE-2026-42880, una vulnerabilità critica di ArgoCD che espone i Kubernetes Secrets tramite ServerSideDiff. Include configurazione automatizzata del laboratorio, script di attivazione e un template di rilevamento Nuclei per test di sicurezza.
Un ambiente di laboratorio per riprodurre e rilevare CVE-2026-42880, una vulnerabilità critica in Argo CD in cui l'handler gRPC ServerSideDiff espone i dati dei Secret Kubernetes a utenti con soli permessi di sola lettura.
| Campo | Dettagli |
|---|---|
| ID CVE | CVE-2026-42880 |
| GHSA | GHSA-3v3m-wc6v-x4x3 |
| CVSS | 9.6 (Critico) — AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N |
| Versioni affette | ArgoCD 3.2.0–3.2.10, 3.3.0–3.3.8 |
| Versioni corrette | 3.2.11, 3.3.9+ |
| CWE | CWE-200, CWE-212 |
serverSideDiff() nell'handler gRPC di ArgoCD chiama la dry-run SSA di Kubernetes e restituisce predictedLive senza chiamare hideSecretData(), esponendo così i valori dei Secret in base64 nella risposta.
Percorso vulnerabile (v3.2.0):
argocd app diff --server-side-diff
→ handler gRPC ServerSideDiff
→ dry-run SSA di Kubernetes (unisce TUTTI i field manager)
← predictedLive restituito (include dati del controller esterno)
❌ hideSecretData() NON chiamata → valori reali del Secret esposti
Percorso corretto (v3.2.11):
...stessa dry-run SSA...
✅ HideSecretData() chiamata → valori sostituiti con ++++
Tutte e tre le condizioni devono essere soddisfatte simultaneamente:
| # | Condizione |
|---|
È richiesto solo il ruolo role:readonly — nessun permesso di scrittura necessario.
Macchina Host
├── localhost:30080 ──→ Cluster Kind: cve-vuln (ArgoCD v3.2.0 ⚠ VULNERABILE)
│ └── ns: production
│ ├── Secret: db-credentials
│ │ metadata → argocd-controller (sincronizzato da Git)
│ │ data.* → external-controller ⚠ (iniettato separatamente)
│ └── Secret: api-credentials (stessa configurazione)
│
├── localhost:30081 ──→ Cluster Kind: cve-patched (ArgoCD v3.2.11 ✓ CORRETTO)
│ └── (configurazione identica — solo versione ArgoCD diversa)
│
└── localhost:3010 ──→ Contenitore Docker: cve-lab-gitea
└── repo: gitadmin/manifests.git
└── secret.yaml (nessun campo data — prerequisito CVE)
Secret db-credentials (namespace: production)
┌──────────────────────────────────────────────────────────────┐
│ metadata.* → argocd-controller (ArgoCD sincronizza da Git) │
│ data.* → external-controller (iniettato dallo script di setup)│
└──────────────────────────────────────────────────────────────┘
Dry-run SSA: Kubernetes unisce i campi di entrambi i manager in predictedLive
→ ArgoCD NON possiede data → data non viene mascherato da ArgoCD
→ v3.2.0 restituisce predictedLive senza hideSecretData() → ESPOSTO
Requisiti di risorse: 8 GB+ di RAM libera, 15 GB+ di spazio su disco, porte 30080 / 30081 / 3010 disponibili.
bash scripts/01-setup-vuln.sh
# oppure: make setup-vuln
Ci vogliono circa 10 minuti. Al termine:
══════════════════════════════════════════════════════
Laboratorio ArgoCD vulnerabile pronto!
══════════════════════════════════════════════════════
Interfaccia ArgoCD: http://localhost:30080
Password admin : <generata automaticamente>
Password viewer : viewerpass123
File token : .vuln-viewer-token
══════════════════════════════════════════════════════
bash scripts/02-setup-patched.sh
# oppure: make setup-patched
bash scripts/03-trigger-cve.sh
# oppure: make trigger
Output atteso — vulnerabile (v3.2.0):
===== /Secret production/db-credentials ======
< db_password: ++++++++ ← stato live mascherato
---
> db_password: U3VwM3JTM2NyM3REQiFQYXNzIzIwMjY= ← predictedLive ESPOSTO!
[ESPOSTO] decodificato: Sup3rS3cr3tDB!Pass#2026
⚠ RISULTATO: DATI DEL SECRET ESPOSTI — VULNERABILE
Output atteso — corretto (v3.2.11):
> db_password: ++++++++ ← mascherato
✓ RISULTATO: nessun dato smascherato in predictedLive — CORRETTO
# Cluster vulnerabile → dovrebbe produrre un risultato [critico]
nuclei -t nuclei/CVE-2026-42880.yaml \
-u http://localhost:30080 \
-var username=viewer \
-var password=viewerpass123
# Cluster corretto → nessun risultato
nuclei -t nuclei/CVE-2026-42880.yaml \
-u http://localhost:30081 \
-var username=viewer \
-var password=viewerpass123
bash scripts/99-teardown.sh
# oppure: make teardown
argocd-cve-2026-42880-lab2/
├── README.md
├── LAB_SETUP_GUIDE.md # Guida setup laboratorio + risoluzione problemi (Inglese)
├── VULNERABILITY_ANALYSIS.md # Analisi vulnerabilità a livello di codice (Inglese)
├── Nuclei_Template_Report.md # Progettazione template Nuclei e risultati test (Inglese)
├── Makefile
│
├── REPORT/ # Report in coreano
│ ├── LAB_REPORT_KR.md
│ ├── Nuclei_Template_Report_KR.md
│ └── Vulnerability_Analysis_KR.md
│
├── kind/
│ ├── cluster-vuln.yaml # Cluster Kind: cve-vuln (porta 30080)
│ └── cluster-patched.yaml # Cluster Kind: cve-patched (porta 30081)
│
├── git-manifests/
│ └── secret.yaml # Secret senza campo data (prerequisito CVE)
│
├── manifests/
│ ├── application.yaml # Applicazione ArgoCD con annotazione vulnerabile
│ ├── argocd-cm-patch.yaml # ConfigMap: TLS disattivato, account viewer, ServerSideDiff
│ ├── argocd-rbac-patch.yaml # RBAC: viewer → role:readonly
│ ├── argocd-nodeport.yaml # NodePort 30080 (cluster vulnerabile)
│ └── argocd-nodeport-patched.yaml# NodePort 30081 (cluster corretto)
│
├── nuclei/
│ └── CVE-2026-42880.yaml # Template di rilevamento Nuclei
│
└── scripts/
├── 01-setup-vuln.sh # Setup automatizzato completo: ambiente vulnerabile
├── 02-setup-patched.sh # Setup automatizzato completo: ambiente corretto
├── 03-trigger-cve.sh # Attiva CVE + confronta entrambi i cluster
└── 99-teardown.sh # Rimuove tutte le risorse del laboratorio
Il template utilizza una catena HTTP a 4 passaggi per verificare tutti i prerequisiti della CVE senza attivare l'estrazione effettiva del Secret:
Passo 1 GET /api/version
→ estrae argocd_version (nessuna autenticazione richiesta)
Passo 2 POST /api/v1/session
→ autentica come viewer (role:readonly), estrae token
Passo 3 GET /api/v1/applications
→ trova app con ServerSideDiff=true,IncludeMutationWebhook=true
Passo 4 GET /api/v1/applications/{app}/managed-resources
→ verifica: versione nell'intervallo + Secret presente + f:data di proprietà di manager esterno
→ RISULTATO segnalato solo se tutti e 5 i matcher passano (condizione AND)
Attenzione: Tutte le credenziali in questo laboratorio sono dati di test fittizi, utilizzati esclusivamente per scopi di ricerca sulla sicurezza. Non utilizzare mai in produzione.
| Dettagli |
|---|
| 1 | Versione ArgoCD vulnerabile | 3.2.0–3.2.10 oppure 3.3.0–3.3.8 |
| 2 | Annotazione dell'applicazione | argocd.argoproj.io/compare-options: ServerSideDiff=true,IncludeMutationWebhook=true |
| 3 | Field manager esterno sui dati del Secret | Campi data del Secret di proprietà di un manager non ArgoCD (es. External Secrets Operator, Helm, kubectl) |
| Strumento | Installazione |
|---|
| kind | brew install kind |
| kubectl | brew install kubectl |
| Docker Desktop | docker.com |
| CLI argocd | brew install argocd |
| nuclei | brew install nuclei |
| curl, jq, git | preinstallati su macOS oppure brew install jq |