CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2025-47933

GitOops: Stored XSS in Argo CD Leads to Cluster Takeover

Amit Schendel
Amit Schendel
Senior Security Researcher

Feb 26, 2026·5 min read·106 visits

Executive Summary (TL;DR)

Argo CD trusted user input when rendering repository URLs. Attackers with 'repo edit' permissions can inject `javascript:` payloads. When an admin views the settings page, the payload executes, allowing the attacker to ride the admin's session to delete apps, steal secrets, or deploy malware.

A critical Stored Cross-Site Scripting (XSS) vulnerability has been discovered in Argo CD, the industry-standard GitOps continuous delivery tool. By injecting a malicious URL protocol into the repository configuration, an attacker can execute arbitrary JavaScript in the browser of any user viewing the repository list—typically a high-privileged administrator. This effectively bridges the gap between low-level configuration access and full Kubernetes cluster compromise.

The Keys to the Kingdom

Argo CD is the darling of the Cloud Native world. It’s the bouncer, the gatekeeper, and the janitor for your Kubernetes clusters. It holds the keys to the castle—literally—managing secrets, deployments, and infrastructure state. If you compromise Argo CD, you don't just get a shell; you get kubectl apply -f ownage.yaml on every cluster it manages.

Usually, we think of XSS as a "medium" severity annoyance—alert boxes and maybe some cookie theft. But context is king. In an administrative dashboard like Argo CD, XSS is the digital equivalent of a Jedi mind trick on the sysadmin. You aren't hacking the server; you are convincing the server that the admin wants to delete the production database. This vulnerability, CVE-2025-47933, turns a simple UI bug into a catastrophic infrastructure collapse.

The Flaw: Trusting the Parser

The road to hell is paved with helpful utility libraries. In this case, the vulnerability lies in how Argo CD's frontend handles Git URLs. To make the UI look pretty, the developers used a library called git-url-parse to break down repository URLs into their component parts (protocol, owner, resource, etc.) and then reassemble them for display.

Here is the logic flaw: The code assumed that if a URL could be parsed, it was safe to display. It took the parsed components and blindly concatenated them back into a string to be used in an href attribute. It failed to ask the most important question in web security: "Is this protocol actually safe?"

By supplying a URL that technically satisfies the parser but utilizes the javascript: pseudo-protocol, an attacker can turn a clickable link into a stored execution trigger. It’s a classic case of sanitization happening in the wrong place—or in this case, not happening at all.

The Code: Anatomy of a Screw-Up

Let's look at the crime scene in ui/src/app/shared/components/urls.ts. The vulnerable function repoUrl takes a string and tries to return a formatted URL.

The Vulnerable Code:

export function repoUrl(url: string): string {
    try {
        const parsed = GitUrlParse(url);
        // The fatal flaw: Blind concatenation without validation
        return `${protocol(parsed.protocol)}://${parsed.resource}/${parsed.owner}/${parsed.name}`;
    } catch {
        return null;
    }
}

See that return statement? It constructs a string using the protocol derived from the input. If I pass in javascript:alert(1), and git-url-parse is lenient enough to treat javascript as the protocol, the function happily returns a valid JS URI.

The Fix:

The patch is simple: validation. The maintainers introduced an isValidURL check that likely whitelists protocols like http, https, ssh, and git.

import {isValidURL} from '../../shared/utils';
 
export function repoUrl(url: string): string {
    try {
        const parsed = GitUrlParse(url);
        const parsedUrl = `${protocol(parsed.protocol)}://${parsed.resource}/${parsed.owner}/${parsed.name}`;
        
        // The Guard Rail
        if (!isValidURL(parsedUrl)) {
            return null;
        }
        return parsedUrl;
    }
}

It’s a three-line fix for a 9.1 CVSS vulnerability. Security is often boring like that.

The Exploit: Weaponizing a Link

So, how do we burn it down? We need two things: access to create/edit a repository, and an admin victim.

Step 1: The Setup

We authenticate as a low-privileged user (perhaps a developer with access to a specific project). We navigate to Settings -> Repositories or use the CLI to register a new repo. Instead of a valid GitHub URL, we provide our payload. The parser might be tricky, so we craft it to look like a valid Git URL structure but with a malicious protocol.

Step 2: The Payload

We inject something nasty. We don't want an alert box; we want persistence.

javascript:fetch('/api/v1/account/password', {method: 'PUT', body: JSON.stringify({currentPassword: '...', newPassword: 'owned'})})

Or perhaps we simply delete the production application:

javascript:fetch('/api/v1/applications/prod-app?cascade=true', {method: 'DELETE'})

Step 3: The Trap

The URL is saved to Kubernetes secrets. Now we wait. An Argo CD administrator logs in to check why a sync failed or to audit the repositories. They navigate to the Repositories page. The UI renders our malicious link. Depending on the browser behavior and the exact rendering, this might trigger on a stray click, or we could style the link to cover the whole screen using CSS injection if the inputs allow it.

Step 4: Game Over

The script executes in the context of the Admin. The browser sends the API request with the Admin's cookies/tokens. The API sees a valid request from a Super Admin. The cluster is yours.

Impact: Why You Should Panic

If you are running a vulnerable version, you are one disgruntled employee or one compromised dev account away from total disaster.

Because Argo CD is declarative, this XSS allows an attacker to rewrite the "truth" of your infrastructure. They could inject a sidecar container into your payment processing pods to skim credit cards. They could modify the OIDC configuration to lock everyone out. They could simply wipe the cluster.

This isn't just a UI bug; it's a privilege escalation tunnel from "I can edit git repos" to "I am Root on the Cluster".

The Fix: Stop the Bleeding

Don't try to get clever with WAF rules here; the payload is stored encrypted in your secrets and rendered by the client. You need to patch the binary.

Update Immediately:

  • If you are on 2.x, go to 2.13.8 or 2.14.13.
  • If you are on 3.x, go to 3.0.4.

If you cannot patch immediately, you must restrict RBAC permissions. Remove repositories, update and repositories, create from all non-admin roles. And for the love of Ops, audit your current repositories:

kubectl get secrets -n argocd -l argocd.argoproj.io/secret-type=repository -o jsonpath="{.items[*].data.url}" | base64 -d

If you see javascript: in there, pull the fire alarm.

Official Patches

Argo ProjectOfficial GitHub Security Advisory
Argo ProjectFix Commit

Fix Analysis (1)

Technical Appendix

CVSS Score
9.1/ 10
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H
EPSS Probability
0.03%
Top 93% most exploited

Affected Systems

Argo CD

Affected Versions Detail

Product
Affected Versions
Fixed Version
Argo CD
Argo Project
>= 1.2.0-rc1, < 2.13.82.13.8
Argo CD
Argo Project
>= 2.14.0-rc1, < 2.14.132.14.13
Argo CD
Argo Project
>= 3.0.0-rc1, < 3.0.43.0.4
AttributeDetail
CWE IDCWE-79 (Cross-Site Scripting)
CVSS v3.19.1 (Critical)
Attack VectorNetwork (Stored in Config)
Privileges RequiredLow (Repo Edit)
ImpactRemote Code Execution (via API)
Patch StatusAvailable

MITRE ATT&CK Mapping

T1189Drive-by Compromise
Initial Access
T1059.007Command and Scripting Interpreter: JavaScript
Execution
T1552Unsecured Credentials
Credential Access
CWE-79
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')

Vulnerability Timeline

Fix committed to master branch
2025-05-28
GHSA-2hj5-g64g-fp6p published
2025-05-29
CVE-2025-47933 assigned
2025-05-29

References & Sources

  • [1]NVD Entry
  • [2]Argo CD Documentation

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•about 3 hours ago•GHSA-534H-C3CW-V3H9
5.5

GHSA-534h-c3cw-v3h9: Local Information Disclosure via Abstract-Namespace Socket in Nuxt Dev Server

A local security vulnerability in the Nuxt development server (nuxt dev) allows local unprivileged users to access sensitive configuration files and source code. On Linux environments running Node.js 20+, Nuxt bound its internal vite-node IPC server to an abstract-namespace Unix socket without any peer authentication, enabling co-resident local users to connect and request module code directly.

Amit Schendel
Amit Schendel
4 views•5 min read
•about 3 hours ago•GHSA-8RFP-98V4-MMR6
0.0

GHSA-8RFP-98V4-MMR6: Protocol-Filtering Bypass via Unicode Obfuscation in Mozilla Bleach

Mozilla Bleach is an open-source HTML sanitizing library for Python. Versions up to and including 6.3.0 contain an incomplete filtering implementation in the URI validation logic ('sanitize_uri_value'). This logic fails to detect disallowed protocols, such as 'javascript:', if they contain Unicode invisible characters, whitespace characters, or characters with a code point greater than U+00A0. While standard-compliant web browsers do not directly execute invalid URI schemes containing these non-standard characters, downstream systems that normalize Unicode text by stripping invisible or non-ASCII characters can unintentionally reactivate the 'javascript:' prefix, causing Cross-Site Scripting (XSS). Additionally, this behavior violates Bleach's core sanitization contract by outputting URIs that bypass protocol allowlists configured by the caller.

Amit Schendel
Amit Schendel
4 views•7 min read
•about 4 hours ago•GHSA-G75F-G53V-794X
4.3

GHSA-G75F-G53V-794X: CPU Exhaustion via Unbounded Email Regular Expression Scanning in Bleach

An uncontrolled resource consumption vulnerability exists in the Python package Bleach when parsing text to linkify email addresses. When `parse_email=True` is enabled, the regular expression engine is forced into a quadratic-time complexity scan on specially crafted payloads lacking an '@' symbol. This causes immediate CPU exhaustion and blocks application server worker processes.

Amit Schendel
Amit Schendel
4 views•6 min read
•about 4 hours ago•GHSA-GR75-JV2W-4656
4.7

GHSA-GR75-JV2W-4656: Path Traversal and Sandbox Escape in LangChain File-Search Middleware and Loaders

A path traversal and sandbox escape vulnerability in LangChain and LangChain-Anthropic Python packages allows unauthenticated local attackers to access files outside the restricted directory via crafted input, symbolic links, or prefix bypasses.

Alon Barad
Alon Barad
3 views•8 min read
•about 5 hours ago•GHSA-M557-WRGG-6RP4
5.8

GHSA-m557-wrgg-6rp4: Server-Side Request Forgery via Authority Information Access (AIA) Chasing in phpseclib

The PHP Secure Communications Library (phpseclib) contains a Server-Side Request Forgery (SSRF) vulnerability due to an insecure default implementation of Authority Information Access (AIA) certificate chasing. This flaw allows remote, unauthenticated attackers to coerce applications validating user-supplied X.509 certificates into generating arbitrary outbound HTTP requests to internal networks or local interfaces.

Amit Schendel
Amit Schendel
4 views•6 min read
•about 5 hours ago•CVE-2026-45491
6.2

CVE-2026-45491: Directory Traversal via Improper Link Resolution in .NET System.Formats.Tar

A directory traversal vulnerability exists in the Microsoft .NET System.Formats.Tar library during archive extraction. When extracting a TAR archive using the TarFile.ExtractToDirectory API, the extraction engine improperly resolves symbolic links prior to file creation, allowing local unauthorized attackers to write or overwrite arbitrary files outside the target directory. This can lead to local tampering, privilege escalation, or arbitrary code execution.

Amit Schendel
Amit Schendel
8 views•6 min read