{"description":"Trending threats, MITRE ATT\u0026CK coverage, and detection metadata. Fed continuously.","feed_url":"https://feed.craftedsignal.io/products/siyuan-kernel-versions-prior-to-0.0.0-20260628153353-2d5d72223df4/feed.json","home_page_url":"https://feed.craftedsignal.io/","items":[{"_cs_actors":[],"_cs_cpes":[],"_cs_cves":[{"cvss":7.5,"id":"CVE-2026-54066"},{"id":"CVE-2026-41894"}],"_cs_exploited":false,"_cs_has_poc":false,"_cs_poc_references":[],"_cs_products":["siyuan kernel (versions prior to 0.0.0-20260628153353-2d5d72223df4)"],"_cs_severities":["high"],"_cs_tags":["path-traversal","vulnerability","web-vulnerability","arbitrary-file-read"],"_cs_type":"advisory","_cs_vendors":["SiYuan"],"content_html":"\u003cp\u003eA critical path traversal vulnerability, tracked as CVE-2026-54066, affects the SiYuan note-taking application in its \u0026quot;publish mode\u0026quot; (anonymous read-only HTTP endpoint, typically port 6808). This flaw is a bypass of the previously incomplete fix for CVE-2026-41894. Unauthenticated remote attackers can exploit this by sending specially crafted HTTP GET requests containing double URL-encoded \u003ccode\u003e..\u003c/code\u003e segments to the \u003ccode\u003e/assets/*path\u003c/code\u003e route. This technique allows them to read arbitrary files from the \u003ccode\u003eWorkspaceDir\u003c/code\u003e outside the intended \u003ccode\u003eDataDir\u003c/code\u003e subtree, including sensitive files like \u003ccode\u003econf/conf.json\u003c/code\u003e (containing API tokens and sync keys) and \u003ccode\u003etemp/*.db\u003c/code\u003e (full notebook content). The vulnerability stems from a second \u003ccode\u003eurl.PathUnescape\u003c/code\u003e operation in a fallback function, coupled with an overly permissive access gate and the non-application of a sensitive path denylist to the \u003ccode\u003e/assets/\u003c/code\u003e route. The vulnerability has been verified against SiYuan v3.6.5 and affects versions prior to \u003ccode\u003e0.0.0-20260628153353-2d5d72223df4\u003c/code\u003e.\u003c/p\u003e\n\u003ch2 id=\"attack-chain\"\u003eAttack Chain\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003eAn unauthenticated remote attacker sends an HTTP GET request to the SiYuan instance's \u0026quot;publish mode\u0026quot; server (default port 6808), targeting the \u003ccode\u003e/assets/*path\u003c/code\u003e endpoint.\u003c/li\u003e\n\u003cli\u003eThe request URL's \u003ccode\u003ecs-uri-stem\u003c/code\u003e contains double URL-encoded path traversal sequences, such as \u003ccode\u003e/assets/%252e%252e/%252e%252e/target/file\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eThe Gin router performs the initial URL decoding, receiving \u003ccode\u003econtext.Param(\u0026quot;path\u0026quot;)\u003c/code\u003e with single URL-encoded segments (e.g., \u003ccode\u003e/%2e%2e/%2e%2e/target/file\u003c/code\u003e).\u003c/li\u003e\n\u003cli\u003eThe \u003ccode\u003eGetAssetAbsPath\u003c/code\u003e function, within its fallback mechanism (\u003ccode\u003ekernel/model/assets.go:548\u003c/code\u003e), performs a second \u003ccode\u003eurl.PathUnescape\u003c/code\u003e on the path.\u003c/li\u003e\n\u003cli\u003eThis second decode converts the single URL-encoded \u003ccode\u003e..\u003c/code\u003e (\u003ccode\u003e%2e%2e\u003c/code\u003e) into literal \u003ccode\u003e..\u003c/code\u003e segments, which \u003ccode\u003efilepath.Join\u003c/code\u003e then processes to resolve a path outside the \u003ccode\u003eDataDir\u003c/code\u003e but still within the \u003ccode\u003eWorkspaceDir\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eThe \u003ccode\u003eCheckAbsPathAccessableByPublishAccess\u003c/code\u003e function evaluates the resolved absolute path. Since the path is outside \u003ccode\u003eDataDir\u003c/code\u003e (e.g., \u003ccode\u003eWorkspaceDir/conf/conf.json\u003c/code\u003e), it incorrectly returns \u003ccode\u003etrue\u003c/code\u003e, bypassing further granular access checks.\u003c/li\u003e\n\u003cli\u003eCrucially, the \u003ccode\u003eIsSensitivePath()\u003c/code\u003e denylist, which is applied to the patched \u003ccode\u003e/export/\u003c/code\u003e route, is not called or enforced for the \u003ccode\u003e/assets/*path\u003c/code\u003e handler.\u003c/li\u003e\n\u003cli\u003eThe \u003ccode\u003ehttp.ServeFile\u003c/code\u003e function then proceeds to serve the arbitrarily specified file from the \u003ccode\u003eWorkspaceDir\u003c/code\u003e, such as \u003ccode\u003econf/conf.json\u003c/code\u003e or \u003ccode\u003etemp/siyuan.db\u003c/code\u003e, to the attacker.\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"impact\"\u003eImpact\u003c/h2\u003e\n\u003cp\u003eSuccessful exploitation allows an unauthenticated attacker to read any file within the SiYuan \u003ccode\u003eWorkspaceDir\u003c/code\u003e. This includes highly sensitive information such as: \u003ccode\u003econf/conf.json\u003c/code\u003e, which contains the \u003ccode\u003eaccessAuthCode\u003c/code\u003e SHA256 hash (vulnerable to offline cracking), API tokens, and S3/WebDAV sync credentials. Attackers can also access \u003ccode\u003etemp/siyuan.db\u003c/code\u003e, \u003ccode\u003etemp/blocktree.db\u003c/code\u003e, and \u003ccode\u003etemp/asset_content.db\u003c/code\u003e, which are SQLite databases containing the entire content of all notebooks. Additionally, \u003ccode\u003esiyuan.log\u003c/code\u003e can be exfiltrated, revealing internal paths and system information. Compromise of the \u003ccode\u003eaccessAuthCode\u003c/code\u003e or API token provides full authenticated access to the kernel API, enabling complete read and write capabilities for all notebooks, and potentially escalating to further compromise if sync credentials are used elsewhere.\u003c/p\u003e\n\u003ch2 id=\"recommendation\"\u003eRecommendation\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003ePatch SiYuan immediately to a version equal to or later than \u003ccode\u003e0.0.0-20260628153353-2d5d72223df4\u003c/code\u003e to remediate CVE-2026-54066.\u003c/li\u003e\n\u003cli\u003eDeploy the \u003ccode\u003eDetect CVE-2026-54066 Exploitation - SiYuan Double URL-Encoded Path Traversal\u003c/code\u003e Sigma rule to your SIEM to identify attempts to exploit this vulnerability.\u003c/li\u003e\n\u003cli\u003eImplement Web Application Firewall (WAF) rules to block HTTP GET requests containing the \u003ccode\u003e%252e%252e\u003c/code\u003e string in the URL path, specifically targeting \u003ccode\u003e/assets/\u003c/code\u003e endpoints, as identified in the IOC.\u003c/li\u003e\n\u003cli\u003eDisable SiYuan's \u0026quot;publish mode\u0026quot; (anonymous read-only HTTP endpoint) if it is not explicitly required for your operational needs, reducing the attack surface.\u003c/li\u003e\n\u003c/ul\u003e\n","date_modified":"2026-07-10T19:30:43Z","date_published":"2026-07-10T19:30:43Z","id":"https://feed.craftedsignal.io/briefs/2026-07-siyuan-path-traversal/","summary":"An incomplete fix for CVE-2026-41894 in SiYuan's 'publish mode' allows unauthenticated remote attackers to perform path traversal by double URL-encoding '..' segments in requests to the '/assets/*path' route, leading to the read of arbitrary files within the 'WorkspaceDir'.","title":"SiYuan Path Traversal Vulnerability (CVE-2026-54066) via Double URL Encoding","url":"https://feed.craftedsignal.io/briefs/2026-07-siyuan-path-traversal/"}],"language":"en","title":"CraftedSignal Threat Feed - Siyuan Kernel (Versions Prior to 0.0.0-20260628153353-2d5d72223df4)","version":"https://jsonfeed.org/version/1.1"}