CVE-2026-25647 Overview
Lute is a structured Markdown engine supporting Go and JavaScript. A Stored Cross-Site Scripting (XSS) vulnerability exists in Lute version 1.7.6 and earlier, as used in SiYuan note-taking application. The vulnerability resides in the Markdown rendering engine and allows attackers to inject malicious JavaScript into Markdown text or notes. When another user views the rendered content, the malicious script executes in the context of their session, potentially leading to session hijacking, data theft, or unauthorized actions.
Critical Impact
Attackers can inject persistent malicious JavaScript that executes when victims view rendered Markdown content, enabling session hijacking and unauthorized access to user data.
Affected Products
- Lute versions 1.7.6 and earlier
- SiYuan note-taking application (versions using vulnerable Lute)
- Applications implementing Lute Markdown engine without sanitization
Discovery Timeline
- 2026-02-06 - CVE CVE-2026-25647 published to NVD
- 2026-02-06 - Last updated in NVD database
Technical Details for CVE-2026-25647
Vulnerability Analysis
This Stored Cross-Site Scripting (XSS) vulnerability (CWE-79) stems from insufficient input sanitization in the Markdown rendering engine. When processing hyperlinks within Markdown content, the Lute engine failed to properly sanitize the href attribute values before rendering them into HTML output. This allows attackers to craft malicious Markdown content containing JavaScript payloads that persist in the application and execute whenever other users view the rendered content.
The vulnerability is particularly concerning in collaborative note-taking environments like SiYuan, where multiple users may share and view Markdown documents. An attacker with basic privileges can inject malicious scripts that execute with the permissions of any user who subsequently views the compromised content.
Root Cause
The root cause lies in the render/protyle_renderer.go file where hyperlink href attributes were processed without proper sanitization when the Sanitize option was enabled. The rendering logic processed URLs containing special characters but did not apply the SanitizeSrc() function to validate and clean potentially malicious URL schemes (such as javascript: URIs) before incorporating them into the rendered HTML output.
Attack Vector
The attack vector is network-based and requires low privileges with user interaction. An authenticated attacker can:
- Create or edit a Markdown note containing a malicious hyperlink
- Inject JavaScript code through specially crafted URL schemes in the href attribute
- Share or make the note accessible to other users
- When victims click the rendered link or the content is processed, the malicious script executes in their browser session
The following patch was applied to address this vulnerability in render/protyle_renderer.go:
if node.ParentIs(ast.NodeTableCell) {
href = strings.ReplaceAll(href, "\\|", "|")
}
if r.Options.Sanitize {
href = SanitizeSrc(href)
}
// 超链接元素地址中存在 `"` 字符时粘贴无法正常解析 https://github.com/siyuan-note/siyuan/issues/11385
href = strings.ReplaceAll(href, "\"", """)
Source: GitHub Commit Changes
The fix introduces a new SanitizeSrc() function in render/sanitizer.go:
"title": nil,
}
func SanitizeSrc(src string) string {
img := strings.ReplaceAll(src, "\"", "__@QUOTE@__")
img = "<img src=\"" + img + "\"></img>"
img = string(sanitize([]byte(img)))
img = string(util.TagSrcStr((img)))
img = strings.ReplaceAll(img, "__@QUOTE@__", "\"")
return img
}
func Sanitize(str string) string {
return string(sanitize([]byte(str)))
}
Source: GitHub Commit Changes
Detection Methods for CVE-2026-25647
Indicators of Compromise
- Presence of javascript: or data: URI schemes within Markdown hyperlinks in stored notes
- Unusual URL patterns in Markdown content containing encoded script tags or event handlers
- User reports of unexpected browser behavior when viewing specific shared notes
- Web application logs showing suspicious script execution attempts originating from rendered Markdown content
Detection Strategies
- Implement Content Security Policy (CSP) headers to detect and block inline script execution
- Monitor stored Markdown content for patterns matching XSS payloads such as javascript:, onerror=, onclick=, and encoded variants
- Deploy web application firewalls (WAF) with XSS detection rules to identify malicious injection attempts
- Audit application logs for unusual rendering activity or error patterns associated with malformed URLs
Monitoring Recommendations
- Enable browser console logging to capture JavaScript errors that may indicate attempted XSS exploitation
- Implement real-time content scanning for user-submitted Markdown before storage
- Monitor for abnormal session activity that could indicate successful script execution and session hijacking
- Track access patterns to shared notes and flag suspicious viewing activity from unexpected sources
How to Mitigate CVE-2026-25647
Immediate Actions Required
- Update Lute to a version newer than 1.7.6 that includes the security patch
- Update SiYuan to the latest version that incorporates the patched Lute library
- Audit existing Markdown content for potentially malicious hyperlinks containing JavaScript payloads
- Implement Content Security Policy headers to restrict inline script execution as a defense-in-depth measure
Patch Information
The vulnerability has been addressed in commit 0118e218916cf0cc7df639b50ce74e0c6c3d1868 to the Lute repository. The fix adds proper URL sanitization by implementing the SanitizeSrc() function and calling it when processing hyperlink href attributes with the sanitize option enabled. Refer to the GitHub Security Advisory GHSA-rw25-98wq-76qv for additional details and updated version information.
Workarounds
- Disable or restrict shared note functionality until the patch can be applied
- Implement server-side content sanitization using a robust HTML sanitizer library before storing or rendering Markdown content
- Deploy Content Security Policy headers with script-src 'self' to prevent execution of injected inline scripts
- Restrict note creation and editing privileges to trusted users in shared environments
# Example: Add Content Security Policy header in nginx configuration
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline';" always;
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


