
CVE-2026-42880 को पुनरुत्पादित करता है, यह एक महत्वपूर्ण ArgoCD कमजोरी है जो ServerSideDiff के माध्यम से Kubernetes Secrets को उजागर करती है। इसमें स्वचालित प्रयोगशाला सेटअप, ट्रिगर स्क्रिप्ट्स और सुरक्षा परीक्षण के लिए एक Nuclei डिटेक्शन टेम्पलेट शामिल है।
CVE-2026-42880 को पुनर्निर्मित और पता लगाने के लिए एक लैब वातावरण, जो Argo CD में एक महत्वपूर्ण कमज़ोरी है जहाँ ServerSideDiff gRPC हैंडलर केवल-पढ़ने वाले उपयोगकर्ताओं को Kubernetes Secret डेटा उजागर करता है।
| क्षेत्र | विवरण |
|---|
| CVE ID | CVE-2026-42880 |
| GHSA | GHSA-3v3m-wc6v-x4x3 |
| CVSS | 9.6 (Critical) — AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N |
| प्रभावित संस्करण | ArgoCD 3.2.0–3.2.10, 3.3.0–3.3.8 |
| पैच किए गए संस्करण | 3.2.11, 3.3.9+ |
| CWE | CWE-200, CWE-212 |
ArgoCD के gRPC हैंडलर में serverSideDiff() Kubernetes SSA ड्राई-रन को कॉल करता है और hideSecretData() को कॉल किए बिना predictedLive लौटाता है, जिससे प्रतिक्रिया में base64-एन्कोडेड Secret मान उजागर हो जाते हैं।
Vulnerable path (v3.2.0):
argocd app diff --server-side-diff
→ gRPC ServerSideDiff handler
→ Kubernetes SSA dry-run (merges ALL field managers)
← predictedLive returned (includes external-controller's data)
❌ hideSecretData() NOT called → real Secret values exposed
Patched path (v3.2.11):
...same SSA dry-run...
✅ HideSecretData() called → values replaced with ++++
सभी तीन शर्तों को एक साथ पूरा किया जाना चाहिए:
| क्रमांक | शर्त | विवरण |
|---|---|---|
| 1 | कमज़ोर ArgoCD संस्करण | 3.2.0–3.2.10 या 3.3.0–3.3.8 |
| 2 | एप्लिकेशन एनोटेशन | argocd.argoproj.io/compare-options: ServerSideDiff=true,IncludeMutationWebhook=true |
| 3 | Secret डेटा पर बाहरी फ़ील्ड प्रबंधक | Secret data फ़ील्ड एक गैर-ArgoCD प्रबंधक (जैसे, External Secrets Operator, Helm, kubectl) के स्वामित्व में हैं |
केवल role:readonly आवश्यक है — किसी लेखन अनुमति की आवश्यकता नहीं है।
Host Machine
├── localhost:30080 ──→ Kind Cluster: cve-vuln (ArgoCD v3.2.0 ⚠ VULNERABLE)
│ └── ns: production
│ ├── Secret: db-credentials
│ │ metadata → argocd-controller (synced from Git)
│ │ data.* → external-controller ⚠ (injected separately)
│ └── Secret: api-credentials (same setup)
│
├── localhost:30081 ──→ Kind Cluster: cve-patched (ArgoCD v3.2.11 ✓ PATCHED)
│ └── (identical config — only ArgoCD version differs)
│
└── localhost:3010 ──→ Docker Container: cve-lab-gitea
└── repo: gitadmin/manifests.git
└── secret.yaml (no data field — CVE prerequisite)
db-credentials Secret (namespace: production)
┌──────────────────────────────────────────────────────────────┐
│ metadata.* → argocd-controller (ArgoCD syncs from Git) │
│ data.* → external-controller (injected by setup script)│
└──────────────────────────────────────────────────────────────┘
SSA dry-run: Kubernetes merges both managers' fields into predictedLive
→ ArgoCD does NOT own data → data is not masked by ArgoCD
→ v3.2.0 returns predictedLive without hideSecretData() → EXPOSED
| उपकरण | स्थापित करें |
|---|---|
| kind | brew install kind |
| kubectl | brew install kubectl |
| Docker Desktop | Docker Desktop |
| argocd CLI | brew install argocd |
| nuclei | brew install nuclei |
| curl, jq, git | macOS पर पूर्व-स्थापित या brew install jq |
संसाधन आवश्यकताएँ: 8GB+ खाली RAM, 15GB+ खाली डिस्क, पोर्ट 30080 / 30081 / 3010 उपलब्ध।
bash scripts/01-setup-vuln.sh
# or: make setup-vuln
इसमें लगभग 10 मिनट लगते हैं। जब हो जाए:
══════════════════════════════════════════════════════
Vulnerable ArgoCD lab ready!
══════════════════════════════════════════════════════
ArgoCD UI : http://localhost:30080
Admin pass : <auto-generated>
Viewer pass : viewerpass123
Token file : .vuln-viewer-token
══════════════════════════════════════════════════════
bash scripts/02-setup-patched.sh
# or: make setup-patched
bash scripts/03-trigger-cve.sh
# or: make trigger
अपेक्षित आउटपुट — कमज़ोर (v3.2.0):
===== /Secret production/db-credentials ======
< db_password: ++++++++ ← masked live state
---
> db_password: U3VwM3JTM2NyM3REQiFQYXNzIzIwMjY= ← EXPOSED predictedLive!
[EXPOSED] decoded: Sup3rS3cr3tDB!Pass#2026
⚠ RESULT: SECRET DATA EXPOSED — VULNERABLE
अपेक्षित आउटपुट — पैच किया गया (v3.2.11):
> db_password: ++++++++ ← masked
✓ RESULT: no unmasked data in predictedLive — PATCHED
# Vulnerable cluster → should produce a [critical] finding
nuclei -t nuclei/CVE-2026-42880.yaml \
-u http://localhost:30080 \
-var username=viewer \
-var password=viewerpass123
# Patched cluster → should produce no findings
nuclei -t nuclei/CVE-2026-42880.yaml \
-u http://localhost:30081 \
-var username=viewer \
-var password=viewerpass123
bash scripts/99-teardown.sh
# or: make teardown
argocd-cve-2026-42880-lab2/
├── README.md
├── LAB_SETUP_GUIDE.md # Lab setup guide + troubleshooting (English)
├── VULNERABILITY_ANALYSIS.md # Code-level vulnerability analysis (English)
├── Nuclei_Template_Report.md # Nuclei template design and test results (English)
├── Makefile
│
├── REPORT/ # Korean reports
│ ├── LAB_REPORT_KR.md
│ ├── Nuclei_Template_Report_KR.md
│ └── Vulnerability_Analysis_KR.md
│
├── kind/
│ ├── cluster-vuln.yaml # Kind cluster: cve-vuln (port 30080)
│ └── cluster-patched.yaml # Kind cluster: cve-patched (port 30081)
│
├── git-manifests/
│ └── secret.yaml # Secret without data field (CVE prerequisite)
│
├── manifests/
│ ├── application.yaml # ArgoCD Application with vulnerable annotation
│ ├── argocd-cm-patch.yaml # ConfigMap: TLS off, viewer account, ServerSideDiff
│ ├── argocd-rbac-patch.yaml # RBAC: viewer → role:readonly
│ ├── argocd-nodeport.yaml # NodePort 30080 (vuln cluster)
│ └── argocd-nodeport-patched.yaml# NodePort 30081 (patched cluster)
│
├── nuclei/
│ └── CVE-2026-42880.yaml # Nuclei detection template
│
└── scripts/
├── 01-setup-vuln.sh # Full automated setup: vulnerable env
├── 02-setup-patched.sh # Full automated setup: patched env
├── 03-trigger-cve.sh # Trigger CVE + compare both clusters
└── 99-teardown.sh # Remove all lab resources
टेम्पलेट वास्तविक Secret निष्कर्षण को ट्रिगर किए बिना सभी CVE पूर्वापेक्षाओं को सत्यापित करने के लिए 4-चरणीय HTTP श्रृंखला का उपयोग करता है:
Step 1 GET /api/version
→ extract argocd_version (no auth required)
Step 2 POST /api/v1/session
→ authenticate as viewer (role:readonly), extract token
Step 3 GET /api/v1/applications
→ find app with ServerSideDiff=true,IncludeMutationWebhook=true
Step 4 GET /api/v1/applications/{app}/managed-resources
→ verify: version in range + Secret present + f:data owned by external manager
→ FINDING reported only if all 5 matchers pass (AND condition)
चेतावनी: इस लैब में सभी क्रेडेंशियल्स केवल सुरक्षा अनुसंधान उद्देश्यों के लिए नकली परीक्षण डेटा हैं। इन्हें उत्पादन में कभी उपयोग न करें।