CVE-2024-40634 Overview
CVE-2024-40634 is a denial-of-service vulnerability in Argo CD, the declarative GitOps continuous delivery tool for Kubernetes. An unauthenticated attacker can send a specially crafted large JSON payload to the /api/webhook endpoint, causing excessive memory allocation. The resulting Out Of Memory (OOM) kill disrupts the Argo CD service and breaks continuous delivery pipelines.
The issue is tracked under [CWE-400] (Uncontrolled Resource Consumption) and is fixed in versions 2.11.6, 2.10.15, and 2.9.20. Because the webhook endpoint is intentionally unauthenticated to support Git provider integrations, any attacker with network reach to the Argo CD API server can trigger the condition.
Critical Impact
Unauthenticated network attackers can crash Argo CD API servers by sending oversized JSON to /api/webhook, halting GitOps deployments cluster-wide.
Affected Products
- Argo CD versions prior to 2.9.20
- Argo CD 2.10.x versions prior to 2.10.15
- Argo CD 2.11.x versions prior to 2.11.6
Discovery Timeline
- 2024-07-22 - CVE-2024-40634 published to NVD
- 2026-06-17 - Last updated in NVD database
Technical Details for CVE-2024-40634
Vulnerability Analysis
Argo CD exposes the /api/webhook endpoint to receive Git provider events from GitHub, GitLab, Bitbucket, and Azure DevOps. The handler parsed inbound JSON without enforcing an upper bound on payload size. An attacker submitting a multi-megabyte or larger JSON body forced the server to allocate proportional memory while parsing the request.
Repeated or single oversized requests pushed memory usage past container limits in Kubernetes deployments. The kernel's OOM killer then terminated the argocd-server process. Because the API server fronts both UI and webhook traffic, its termination interrupts application synchronization and reconciliation for every workload Argo CD manages.
Root Cause
The webhook handler lacked a configurable maximum payload size. The fix introduces a new setting key webhook.maxPayloadSizeMB and passes a size limit into webhook.NewHandler via a.settingsMgr.GetMaxWebhookPayloadSize(). Requests exceeding the bound are rejected before memory is allocated for parsing.
Attack Vector
The attack requires only network access to the Argo CD API server. No authentication, user interaction, or privileges are needed. Attackers can script the request directly against the publicly reachable /api/webhook route.
// Security patch in server/server.go
// Webhook handler for git events (Note: cache timeouts are hardcoded because
// API server does not write to cache and not really using them)
argoDB := db.NewDB(a.Namespace, a.settingsMgr, a.KubeClientset)
-acdWebhookHandler := webhook.NewHandler(a.Namespace, a.ArgoCDServerOpts.ApplicationNamespaces, a.AppClientset, a.settings, a.settingsMgr, repocache.NewCache(a.Cache.GetCache(), 24*time.Hour, 3*time.Minute), a.Cache, argoDB)
+acdWebhookHandler := webhook.NewHandler(a.Namespace, a.ArgoCDServerOpts.ApplicationNamespaces, a.AppClientset, a.settings, a.settingsMgr, repocache.NewCache(a.Cache.GetCache(), 24*time.Hour, 3*time.Minute), a.Cache, argoDB, a.settingsMgr.GetMaxWebhookPayloadSize())
mux.HandleFunc("/api/webhook", acdWebhookHandler.Handler)
// Source: https://github.com/argoproj/argo-cd/commit/46c0c0b64deaab1ece70cb701030b76668ad0cdc
The patch adds the new settings key in util/settings/settings.go:
settingsWebhookAzureDevOpsUsernameKey = "webhook.azuredevops.username"
// settingsWebhookAzureDevOpsPasswordKey is the key for Azure DevOps webhook password
settingsWebhookAzureDevOpsPasswordKey = "webhook.azuredevops.password"
+// settingsWebhookMaxPayloadSize is the key for the maximum payload size for webhooks in MB
+settingsWebhookMaxPayloadSizeMB = "webhook.maxPayloadSizeMB"
// Source: https://github.com/argoproj/argo-cd/commit/540e3a57b90eb3655db54793332fac86bcc38b36
Detection Methods for CVE-2024-40634
Indicators of Compromise
- Unexpected restarts of the argocd-server pod accompanied by Kubernetes OOMKilled events.
- HTTP POST requests to /api/webhook with Content-Length values significantly larger than legitimate Git provider payloads.
- Spikes in container memory usage that correlate with inbound traffic to the API server.
Detection Strategies
- Monitor Kubernetes events for Reason=OOMKilled on the argocd-server deployment and alert on repeated occurrences.
- Inspect ingress or service mesh access logs for /api/webhook requests from source IPs outside known Git provider ranges.
- Compare webhook request sizes against the configured webhook.maxPayloadSizeMB and alert on rejected oversized requests.
Monitoring Recommendations
- Track the process_resident_memory_bytes and container_memory_working_set_bytes metrics for argocd-server and alert on sudden growth.
- Forward argocd-server logs and Kubernetes audit events to a centralized analytics platform for correlation across replicas.
- Enable rate limiting and request-size logging at the ingress controller in front of Argo CD.
How to Mitigate CVE-2024-40634
Immediate Actions Required
- Upgrade Argo CD to 2.11.6, 2.10.15, 2.9.20, or later as soon as possible.
- Restrict network exposure of the Argo CD API server so /api/webhook is only reachable from trusted Git provider IP ranges.
- Configure resource limits and Horizontal Pod Autoscaler thresholds for argocd-server to contain memory spikes during the upgrade window.
Patch Information
The fix is delivered through commits 46c0c0b, 540e3a5, and d881ee7, and is documented in the GitHub Security Advisory GHSA-jmvp-698c-4x3w. The patch introduces the webhook.maxPayloadSizeMB setting, which enforces a configurable upper bound on JSON payload size before parsing.
Workarounds
- Place a reverse proxy or ingress controller in front of Argo CD that enforces a strict client_max_body_size on the /api/webhook path.
- Use a Web Application Firewall (WAF) rule to block POST requests to /api/webhook that exceed a defined byte threshold.
- Apply Kubernetes NetworkPolicy resources to allow inbound traffic to argocd-server only from approved Git provider CIDRs.
# Nginx ingress annotation to cap webhook payload size at 1MB
metadata:
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: "1m"
nginx.ingress.kubernetes.io/server-snippet: |
location /api/webhook {
client_max_body_size 1m;
}
# After upgrading, set the in-product limit via the argocd-cm ConfigMap
kubectl -n argocd patch configmap argocd-cm --type merge \
-p '{"data":{"webhook.maxPayloadSizeMB":"1"}}'
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

