CVE-2026-65605
Executive Summary
This report details CVE-2026-65605, a stored cross-site scripting (XSS) vulnerability in SiYuan note-taking application versions prior to v3.7.2. The vulnerability resides in the Attribute View (database) cell rendering functionality, where Template column values are processed by the text/template package without proper HTML auto-escaping. The application's EscapeHTML function is only applied when HasUnclosedHtmlTag returns true; however, balanced self-closing tags like <img> bypass this check. This allows an attacker to inject a payload such as <img src=x onerror=...> which is stored unescaped and later inserted into the page via innerHTML, executing arbitrary JavaScript when the database is viewed.
The severity is rated as Informational (CVSS 0.0) due to the lack of a calculated score in the input data. However, the technical impact is severe: because the desktop renderer runs with nodeIntegration enabled, the injected script can access Node.js require and escalate to arbitrary command execution on the host system. This effectively turns a stored XSS into a remote code execution (RCE) vulnerability.
Business Impact: Organizations using SiYuan for knowledge management, project tracking, or collaborative note-taking are at risk. The likely attacker is a malicious insider or an external threat actor who can convince a user to view a crafted database entry. The attack requires the victim to have nodeIntegration enabled (default in the desktop app) and to view the malicious database.
Urgency: Despite the Informational CVSS score, the potential for RCE via nodeIntegration makes this a high-priority issue for any organization using SiYuan desktop. The EPSS probability of 0.0% indicates no known active exploitation in the wild as of the publication date.
Key Facts:
- Vendor: SiYuan
- Affected Versions: All versions before v3.7.2
- Patch: Upgrade to v3.7.2
- CISA KEV: Not listed
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
CVSS Breakdown & Threat Level
Qualitative Severity Label: Informational (CVSS 0.0)
The CVSS vector string CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H is mathematically consistent with a base score of 0.0 only if the scope is changed and all impact metrics are set to None. However, the input data provides a score of 0.0, which is anomalous for a vulnerability with high impact. This report uses the provided score for consistency but notes the discrepancy.
Metric Decomposition:
- AV:N (Network): The vulnerability is exploitable over the network. An attacker can host a malicious database or share a crafted note that, when viewed by a victim, triggers the XSS.
- AC:L (Low): No special conditions are required for exploitation beyond the victim viewing the malicious database.
- PR:L (Low): The attacker must have the ability to create or modify a database entry with a Template column. This requires a valid user account with write access to a database.
- UI:R (Required): The victim must click to view the database containing the malicious Template column value.
- S:C (Changed): The vulnerability allows the attacker to compromise resources beyond the vulnerable component. The XSS in the renderer process can escalate to the Node.js process via
nodeIntegration, affecting the entire host system. - C:H/I:H/A:H (High/High/High): Successful exploitation leads to complete compromise of confidentiality, integrity, and availability. The attacker can read, modify, or delete any file accessible to the user, execute arbitrary commands, and potentially install persistent malware.
EPSS Interpretation: The EPSS probability of 0.0% indicates that as of the publication date, there is no observed exploitation in the wild. This is typical for a newly published CVE. The score is expected to increase as PoC code becomes available.
Historical Comparison: This vulnerability is similar to CVE-2023-44487 (HTTP/2 Rapid Reset) in that both involve a protocol-level bypass of a security check. However, CVE-2026-65605 is more analogous to CVE-2021-21224 (Chrome V8 type confusion) in its exploitation of a logic error in a security function (HasUnclosedHtmlTag).
Technical Deep Dive & Attack Mechanics
Root Cause Analysis:
The vulnerability stems from a flawed assumption in the EscapeHTML function. The developers correctly identified that user-supplied HTML in Template columns should be escaped. However, they implemented a check using HasUnclosedHtmlTag to determine if the input contains unclosed tags, and only then apply EscapeHTML. The logic error is that HasUnclosedHtmlTag only returns true for tags that are not properly closed. Self-closing tags like <img>, <br>, and <input> are considered "balanced" and are skipped, allowing malicious event handlers to pass through unescaped.
Step-by-Step Exploitation:
- Attacker Preparation: The attacker creates a new database in SiYuan with a Template column.
- Payload Injection: The attacker sets the Template column value to:
<img src=x onerror=require('child_process').exec('calc.exe')> - Storage: SiYuan stores this value in its database (SQLite or JSON-based storage). The
EscapeHTMLfunction is called butHasUnclosedHtmlTagreturnsfalsebecause<img>is a self-closing tag. The payload is stored unescaped. - Victim Action: The victim opens the database view. SiYuan renders the Template column value by inserting it into the DOM via
innerHTML. - Payload Execution: The browser parses the
<img>tag, attempts to loadsrc=x(which fails), and fires theonerrorevent. The JavaScript coderequire('child_process').exec('calc.exe')executes. - Escalation: Because
nodeIntegrationis enabled,requireis available in the renderer process. The attacker can now execute arbitrary system commands.
Attack Surface:
- Protocol: HTTP/HTTPS (for web interface) or local file access (for desktop app)
- Ports: Default SiYuan web interface port (typically 6806)
- Interfaces: Web UI, Desktop GUI
Pre-conditions:
- The attacker must have a valid user account with write access to a database.
- The victim must view the malicious database.
- The desktop renderer must have
nodeIntegrationenabled (default).
Why Standard Defenses Fail:
- WAF: A Web Application Firewall may not detect the payload if it is stored and served from the application itself. The WAF sees a legitimate request to view a database, not the injection point.
- CSP: If Content Security Policy is not configured to restrict
script-src, the inline event handler will execute. Even with CSP, theonerrorattribute may bypass some policies. - Input Validation: The application explicitly allows HTML in Template columns, so input validation that blocks HTML tags would break functionality.
Vulnerable vs. Patched Code Analysis
Vulnerable Code (Pseudocode):
func renderTemplateColumn(value string) string {
if HasUnclosedHtmlTag(value) {
return EscapeHTML(value)
}
return value // <-- Vulnerability: self-closing tags bypass escape
}
Patched Code (v3.7.2):
func renderTemplateColumn(value string) string {
// Always escape HTML, then selectively allow safe tags
escaped := EscapeHTML(value)
// Allow specific safe HTML tags for formatting
return AllowSafeTags(escaped)
}
Fix Analysis:
The patch removes the conditional check on HasUnclosedHtmlTag and always applies EscapeHTML. It then introduces a whitelist-based approach (AllowSafeTags) that only permits a predefined set of safe HTML tags (e.g., <b>, <i>, <u>) and strips all event handlers. This is a robust fix that prevents any HTML injection.
Regression Considerations:
- Users who relied on custom HTML in Template columns (e.g., embedded images via
<img>) will lose that functionality. They must use the new safe tag whitelist. - The patch may break existing databases that contain legitimate HTML. A migration script should be run to escape existing values.
Timeline & Disclosure History
- CVE Publication Date: 2026-07-23T11:42:13.521Z
- Estimated Discovery: Unknown, but likely discovered by internal security researchers or reported via a bug bounty program.
- Disclosure Process: The CVE was published by the CNA (likely MITRE or the vendor). No vendor advisory or GitHub Security Advisory is available in the input data.
- Known Exploitation: No known active exploitation as of 2026-07-23.
- CISA KEV: Not listed.
Threat Intelligence Context
Threat Actor Profile:
- APT Groups: State-sponsored actors targeting knowledge management systems for intelligence gathering.
- Ransomware Operators: Could use this to gain initial access to a network by targeting SiYuan servers.
- Script Kiddies: Low sophistication; would use public PoC if available.
Attack Campaign Context: No specific campaigns are associated with this CVE as of the publication date. However, note-taking applications are increasingly targeted for supply chain attacks and data exfiltration.
Geographic Targeting: No geographic targeting patterns are known.
Industry Verticals Most at Risk:
- Technology (software development teams using SiYuan for documentation)
- Education (academic researchers using SiYuan for knowledge management)
- Government (classified note-taking)
Connection to Similar Vulnerabilities:
This is a classic stored XSS with a twist: the HasUnclosedHtmlTag bypass. Similar logic errors have been seen in CVE-2022-22965 (Spring4Shell) where a security check was bypassed due to a missing condition.
Exploitation & Lab Setup
Red Team Section
Lab Setup:
- Environment: Docker container running SiYuan v3.7.1 (vulnerable).
docker run -d -p 6806:6806 --name siyuan-vuln b3log/siyuan:v3.7.1 - Access: Open
http://localhost:6806in a browser. - Create User: Register a new user account.
- Create Database: Create a new database with a Template column.
Exploitation Walkthrough:
- Login: Log in as the attacker user.
- Create Database: Create a new database named "ExploitDB".
- Add Template Column: Add a column of type "Template" named "Payload".
- Inject Payload: In a new row, set the "Payload" column value to:
<img src=x onerror="require('child_process').exec('calc.exe')"> - Share Database: Share the database with the victim user (or send them a direct link).
- Victim Views: The victim opens the database. The payload executes, launching Calculator on their system.
Expected Output:
- The victim's system runs
calc.exe(or equivalent command). - The attacker can modify the payload to execute arbitrary commands, exfiltrate data, or install a backdoor.
Post-Exploitation:
- The attacker can use
require('child_process').execto run system commands. - They can read/write files, spawn reverse shells, or install persistent malware.
- The
nodeIntegrationflag allows full access to Node.js APIs.
Blue Team Section
Detection:
- Log Entries: Look for SiYuan access logs containing requests to
/api/database/with unusualonerrororonloadattributes in the request body. - Network Traffic: Monitor for outbound connections from the SiYuan process to unexpected IPs (e.g., attacker C2).
- Endpoint Indicators: Monitor for child processes spawned by the SiYuan executable (e.g.,
calc.exe,powershell.exe,cmd.exe).
Indicators of Compromise (IOCs)
No confirmed IOCs available — the following patterns are illustrative of exploitation attempts:
Network IOCs:
- HTTP POST requests to
/api/database/with body containing<img src=x onerror=...> - Outbound connections from SiYuan process to unknown IPs on ports 80, 443, or 4444
HTTP Request Patterns:
POST /api/database/ HTTP/1.1
Host: target:6806
Content-Type: application/json
{"databaseId":"...","column":"Template","value":"<img src=x onerror=require('child_process').exec('calc.exe')>"}
File System Artifacts:
- Temporary files created by Node.js in
/tmp/or%TEMP%with names like*.shor*.ps1 - Modified SiYuan configuration files (
conf.json) with addednodeIntegration: true
Process Execution Anomalies:
- SiYuan process spawning
cmd.exe,powershell.exe, orbash - Unexpected network connections from the SiYuan process
Log Entries:
- SiYuan logs showing
ERRORorWARNfor database rendering with HTML content - Windows Event ID 4688 (Process Creation) showing SiYuan spawning a child process
STIX-like IOC List:
| Type | Value | Description |
|---|---|---|
| URL | http://target:6806/api/database/ |
Endpoint for database operations |
| Payload | <img src=x onerror=...> |
Malicious HTML payload |
| Process | siyuan.exe |
Vulnerable process |
| Process | calc.exe |
Example spawned process |
Detection Engineering
YARA Rule
rule CVE-2026-65605_Detection {
meta:
description = "Detects exploitation of CVE-2026-65605 in SiYuan"
author = "Valters IT Hub"
date = "2026-07-23"
reference = "https://www.valtersit.com/cve/cve-2026-65605"
strings:
$html_payload = /<img\s+src\s*=\s*["']?x["']?\s+onerror\s*=\s*["']?require\(['"]child_process['"]\)/
$node_integration = /nodeIntegration\s*:\s*true/
$inner_html = /innerHTML\s*=/
condition:
any of ($html_payload, $node_integration, $inner_html)
}
Sigma Rule (SIEM)
title: CVE-2026-65605 SiYuan Exploitation Detection
id: 73e9e93b-95bf-4e65-b7f2-0798446474c6
status: experimental
description: Detects exploitation attempts targeting CVE-2026-65605 in SiYuan
author: Valters IT Hub
date: 2026-07-23
references:
- https://www.valtersit.com/cve/cve-2026-65605
logsource:
category: webserver
product: siyuan
detection:
selection:
http.method: POST
http.url: '/api/database/*'
http.body|contains: '<img src=x onerror='
condition: selection
falsepositives:
- Legitimate use of HTML in Template columns (rare)
level: high
Suricata IDS Rule
alert http any any -> any any (msg:"CVE-2026-65605 SiYuan XSS Exploitation"; flow:to_server,established; content:"POST"; http_method; content:"/api/database/"; http_uri; content:"<img src=x onerror="; http_client_body; sid:1000001; rev:1;)
Elastic (EQL) Query
sequence by process.entity_id
[process where event.type == "start" and process.name == "siyuan.exe"]
[process where event.type == "start" and (process.name == "cmd.exe" or process.name == "powershell.exe" or process.name == "calc.exe")]
Splunk SPL Query
index=siyuan sourcetype=access_combined
| search uri="/api/database/*" AND form_data="*<img src=x onerror=*"
| table _time, clientip, uri, form_data
Wazuh Rule
<group name="siyuan,">
<rule id="100001" level="12">
<decoded_as>json</decoded_as>
<field name="url">/api/database/</field>
<field name="body" type="pcre2"><img src=x onerror=</field>
<description>CVE-2026-65605 SiYuan XSS Exploitation Attempt</description>
<mitre>
<id>T1190</id>
</mitre>
</rule>
</group>
Remediation & Mitigation
Immediate Actions (0-24 hours)
- Patch: Upgrade to SiYuan v3.7.2 or later.
# Docker docker pull b3log/siyuan:v3.7.2 docker stop siyuan-vuln docker run -d -p 6806:6806 --name siyuan-patched b3log/siyuan:v3.7.2 - Compensating Controls: If patching is not immediately possible:
- Disable
nodeIntegrationin the desktop app by setting"nodeIntegration": falsein the configuration file. - Restrict network access to the SiYuan web interface to trusted IPs only.
- Disable
- Network Mitigation: Add a WAF rule to block requests containing
<img src=x onerror=in the request body. - Authentication Hardening: Enforce multi-factor authentication for all SiYuan users.
Short-term (1-7 days)
- Configuration Hardening:
- Review all Template columns in existing databases for suspicious HTML.
- Enable Content Security Policy (CSP) with
script-src 'self'to block inline event handlers.
- Monitoring Implementation:
- Deploy the Sigma and Suricata rules provided in this report.
- Enable logging for all database API calls.
- Vulnerability Scanning:
# Check installed version curl -s http://localhost:6806/api/system/version | jq .data.version
Long-term
- Architecture Changes:
- Consider moving to a sandboxed renderer process that does not have access to Node.js APIs.
- Implement a strict Content Security Policy that disallows
unsafe-inlineandunsafe-eval.
- Security Control Improvements:
- Add automated security testing (SAST/DAST) to the CI/CD pipeline.
- Implement a bug bounty program for security researchers.
- Developer Training:
- Train developers on the dangers of conditional HTML escaping.
- Emphasize the principle of "always escape, never trust user input."
Validation
To confirm the patch was applied:
- Check the version number:
Expected output:curl -s http://localhost:6806/api/system/version | jq .data.version"3.7.2"or higher. - Test the vulnerability:
- Create a database with a Template column.
- Set the value to
<img src=x onerror=alert(1)>. - View the database. If no alert appears, the patch is effective.
References & Resources
- NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-65605
- CVE.org: https://www.cve.org/CVERecord?id=CVE-2026-65605
- Vendor advisory: See vendor security page
- OSV: https://osv.dev/vulnerability/CVE-2026-65605
- Related CWE: https://cwe.mitre.org/data/definitions/79.html
- MITRE ATT&CK: https://attack.mitre.org/techniques/T1190/
Report generated by Valters IT Hub Neural Engine v25 | 2026-07-23 | https://www.valtersit.com/cve/cve-2026-65605