{"schema":"threatline.record/2","record":{"id":"GHSA-fmj3-xc2f-6w4w","aliases":["GHSA-fmj3-xc2f-6w4w"],"summary":"javascript: URI in the check-auth redirect parameter executes script in the kernel origin after login","details":"### Summary\r\n\r\nThe unauthenticated authorization page served at `/check-auth` accepts a `to` query parameter as the post-login destination and assigns it to `window.location.href` without any scheme validation. A crafted `to` value using the `javascript:` scheme therefore executes as script in the kernel origin as soon as the victim completes authentication on the crafted URL. The behavior was verified end to end on SiYuan v3.8.6 (the latest release at the time of reporting) and is present in every release since v2.9.0.\r\n\r\n### Details\r\n\r\nThe page source `app/stage/auth.html` reads the redirect target at line 459 with `toPath = url.searchParams.get(\"to\") || \"/\"`. Two sinks assign this value to the browser location after a successful login: line 638, inside the handler for the `fetch(\"/api/system/loginAuth\")` response when `response.code` is 0, and line 722, inside the `onmessage` handler for the `loginAuth` WebSocket push, which performs the same `window.location.href = toPath` assignment. The `/check-auth` route is registered without an authentication check in `kernel/server/serve.go`, so an attacker can send a victim a link of the form `http://<host>:6806/check-auth?to=javascript:...` and the unvalidated value is embedded in the page that victim then authenticates on. No stored content or renderer injection is involved, which distinguishes this from the previously published cross-site scripting advisories for SiYuan (GHSA-mjf3-jwmf-r6wf, GHSA-jjq3-3942-x99r, GHSA-jf56-jrhq-j2qp, GHSA-5prr-vgxq-69g9, GHSA-7h8j-qw37-w46g, GHSA-v6wf-r2gr-rrgf, GHSA-rvcf-q4h8-w6c9, GHSA-qcw6-qm34-28h8 and related), all of which are stored XSS in content renderers; none of them involves the auth page or the `to` parameter. Source-level regression dating across release tags shows the sink is absent in v2.8.0, first appears in v2.9.0 at line 509 as `window.location.href = url.searchParams.get(\"to\") || \"/\"`, and persists through v3.8.6, where the refactored `toPath` variable adds the second WebSocket-triggered sink.\r\n\r\n### Proof of concept\r\n\r\nSend the victim a link pointing at the kernel with a `javascript:` URI in the `to` parameter, for example `http://<host>:6806/check-auth?to=javascript:document.title%3D%22poc%22%3Bvoid%200`. The page is served without authentication, HTTP 200, and its script contains the unvalidated sink. The victim enters the valid access auth code in the page's own input and clicks the page's own submit button; `loginAuth` returns code 0 and the page's success handler executes `window.location.href = toPath`, which runs the `javascript:` URI in the kernel origin. In the verified run the document title of the still kernel-origin page changed to `poc`, and from that point script runs with the victim's authenticated session and can call the kernel's same-origin APIs.\r\n\r\n### Impact\r\n\r\nAn attacker who convinces a user to open a crafted check-auth link and authenticate on it gains arbitrary script execution in the authenticated kernel origin. The script inherits the victim's session and can invoke the kernel's same-origin APIs, which for an administrator include reading and modifying workspace content and changing kernel settings. Impact is bounded by the user-assisted precondition, since the attacker needs the victim to both open the crafted URL and complete a valid login on it.","categories":["Unclassified"],"product":"siyuan-note/siyuan","vendor":"","ecosystem":null,"affected_ranges":[{"source":"GitHub Advisory Database","source_url":"https://github.com/siyuan-note/siyuan/security/advisories/GHSA-fmj3-xc2f-6w4w","source_modified_at":"2026-10-09T12:47:38Z","fetched_at":"2026-10-26T19:10:57.178988Z","package":{"ecosystem":"go application","name":"siyuan-note/siyuan"},"range":">= 2.9.0, <= 3.8.6"}],"fixed_versions":[],"cvss":6.8,"severity":"Medium","kev":{"listed":false},"epss":{"probability":null,"percentile":null,"score_date":null},"published_at":"2026-10-09T12:47:38Z","modified_at":"2026-10-09T12:47:38Z","provenance":[{"source":"GitHub Advisory Database","url":"https://github.com/siyuan-note/siyuan/security/advisories/GHSA-fmj3-xc2f-6w4w","fetched_at":"2026-10-26T19:10:57.178988Z","source_modified_at":"2026-10-09T12:47:38Z"}],"sources":["GitHub Advisory Database"],"references":[],"locations":[],"motoko_assessment":{"status":"requires_architecture_review","automatic_remediation":false},"classification":{"method":"product-first software-layer rules","rules_version":"2.1","matched_on":null,"confidence":"unknown","reviewed":false},"change_timestamp":"2026-10-09T12:47:38Z","content_hash":"679ff32de050a1c5e50c9d5900edc64d36eae45db1ba9eca6093e3ce53a86cae"}}
