CVE-2026-31809: 
NixOS vulnerability analysis and mitigation

Overview

CVE-2026-31809 is a reflected Cross-Site Scripting (XSS) vulnerability in SiYuan, a personal knowledge management system, caused by a bypass of the SVG sanitizer's javascript: URI prefix check. The flaw affects all SiYuan versions prior to 3.5.10 and was disclosed on March 9–10, 2026. It represents a second bypass of the fix introduced in v3.5.9 for CVE-2026-29183. The vulnerability carries a CVSS v3.1 base score of 6.1 (Medium) and a CVSS v4.0 base score of 6.4 (Medium) (GitHub Advisory, SiYuan Advisory).

Technical details

The root cause (CWE-79) lies in kernel/util/misc.go within the SanitizeSVG() function (lines 234–319). The sanitizer uses Go's html.Parse to decode HTML entities in attribute values, then checks for the javascript: prefix using strings.HasPrefix(). When an attacker inserts HTML-encoded ASCII tab (	), newline (
), or carriage return (
) characters within the javascript: string (e.g., java	script:), the HTML parser decodes them to literal whitespace characters embedded in the middle of the string. Because strings.TrimSpace only strips leading/trailing whitespace and strings.HasPrefix performs a literal match, the check fails to detect the malicious scheme. However, per the WHATWG URL specification, browsers strip these internal tab/newline/CR characters before parsing the URL scheme, causing the browser to interpret the href as a valid javascript: URI and execute the payload. The unauthenticated GET /api/icon/getDynamicIcon?type=8&content=... endpoint is the attack surface, and a proof-of-concept with concrete HTTP requests is publicly available (SiYuan Advisory).

Impact

Successful exploitation allows an unauthenticated remote attacker to inject and execute arbitrary JavaScript in the browser of any user who clicks a crafted link to the /api/icon/getDynamicIcon endpoint. Because the script executes within SiYuan's application origin, an attacker can steal session cookies, API tokens, or authentication credentials, and make authenticated API calls on behalf of the victim. This can lead to full account takeover, data exfiltration from the knowledge base, and potential lateral movement within the user's environment (SiYuan Advisory, GitHub Advisory).

Exploitability

A proof-of-concept exploit consisting of concrete, reproducible HTTP GET requests with specific whitespace-encoded payloads is publicly documented in the GitHub Security Advisory (SiYuan Advisory). The vulnerability requires no authentication and only passive user interaction (clicking a link), making it straightforward to weaponize via phishing or malicious redirects. Nuclei templates for automated detection have been added to the ProjectDiscovery nuclei-templates repository. The EPSS score is approximately 0.054% (per Feedly data), and there is no evidence of active in-the-wild exploitation or CISA KEV catalog listing at this time (GitHub Advisory).

Exploitation steps

  1. Reconnaissance: Identify internet-accessible SiYuan instances running versions ≤ 3.5.9. The /api/icon/getDynamicIcon endpoint requires no authentication and can be probed directly.
  2. Craft malicious payload: Construct an SVG injection payload embedding a javascript: URI with an internal whitespace character to bypass the sanitizer. For example, use an HTML-encoded tab character (	) between java and script: within an anchor href attribute inside the SVG content parameter.
  3. Build the exploit URL: Encode the payload into the content query parameter of the target endpoint, e.g.:
    GET /api/icon/getDynamicIcon?type=8&content=</text><a href="java&#9;script:alert(document.domain)">Click me</a>&color=blue
  4. Deliver the link: Send the crafted URL to the victim via phishing email, social engineering, or embed it in a page that redirects the victim to the malicious URL.
  5. Victim interaction: The victim navigates to the URL; the server responds with an SVG (Content-Type: image/svg+xml) containing the unsanitized anchor element.
  6. JavaScript execution: The victim clicks the rendered link in the SVG. The browser strips the embedded tab per the WHATWG URL spec and executes javascript:alert(document.domain) (or a more malicious payload) in SiYuan's origin.
  7. Post-exploitation: The attacker's JavaScript exfiltrates session cookies, API tokens, or makes authenticated API calls to steal data or escalate access (SiYuan Advisory).

Indicators of compromise

  • Network: Unusual or unexpected HTTP GET requests to /api/icon/getDynamicIcon containing HTML-encoded whitespace characters (%26%239%3B, &#9;, &#10;, &#13;, or their URL-encoded equivalents) within the content parameter; outbound requests from the SiYuan server or client to unknown external hosts following such requests.
  • Logs: Web server or application access logs showing requests to /api/icon/getDynamicIcon?type=8&content= with <a href= patterns and encoded whitespace in the content value; repeated requests from the same IP with varying payload encodings.
  • File System: No persistent file artifacts are expected for this reflected XSS; however, if post-exploitation tools are deployed, watch for unexpected new files in the SiYuan data directory or OS temp directories.
  • Process/Browser: Unexpected JavaScript-initiated network connections from the browser process to attacker-controlled infrastructure after a user visits a SiYuan icon URL (SiYuan Advisory).

Mitigation and workarounds

Upgrade SiYuan to version 3.5.10 or later, which replaces the flawed strings.HasPrefix check with a whitespace-stripped comparison that removes ASCII tab, newline, and carriage return characters before evaluating the javascript: prefix (GitHub Advisory, SiYuan Advisory). As a temporary workaround if patching is not immediately possible, restrict or disable network access to the /api/icon/getDynamicIcon endpoint via firewall rules or reverse proxy ACLs, and prevent users from following untrusted links to SiYuan icon URLs. Implementing a Content Security Policy (CSP) that blocks inline script execution can also reduce the impact of any successful XSS.

Community reactions

The vulnerability was reported by security researcher 0xkakash1 and disclosed via GitHub Security Advisories on March 9, 2026 (SiYuan Advisory). A Bluesky post from the account beikokucyber.bsky.social referenced the vulnerability shortly after disclosure. ProjectDiscovery added Nuclei detection templates for CVE-2026-31809 to their nuclei-templates repository, indicating community interest in automated scanning. No major vendor statements or broad media coverage beyond the advisory and vulnerability database entries have been identified.

Additional resources


Source: This report was generated using AI

Related NixOS vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

CVE-2026-103493HIGH8.1
  • YouTrack logoYouTrack
  • cpe:2.3:a:jetbrains:youtrack
NoYesOct 01, 2026
CVE-2026-103494MEDIUM6.6
  • YouTrack logoYouTrack
  • youtrack
NoYesOct 01, 2026
CVE-2026-103497MEDIUM5.5
  • YouTrack logoYouTrack
  • youtrack
NoYesOct 01, 2026
CVE-2026-103496MEDIUM5.4
  • YouTrack logoYouTrack
  • youtrack
NoYesOct 01, 2026
CVE-2026-103495MEDIUM4.3
  • YouTrack logoYouTrack
  • cpe:2.3:a:jetbrains:youtrack
NoYesOct 01, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management