From 61d47f18336cfef2514c9acdaf6c2a62c40bceb4 Mon Sep 17 00:00:00 2001 From: Quang Do Date: Wed, 10 Jun 2026 00:09:12 +0700 Subject: [PATCH 1/2] fix(security)(pkg): prototype pollution via untrusted yaml user-config parseUserConfig() copies YAML group names directly into a plain object (`ret[groupKey] = groupValue`). A malicious userscript can use special keys such as `__proto__`, `constructor`, or `prototype` to mutate object prototypes or interfere with later merges/lookups. Because this parser handles untrusted script metadata, this can become a cross-script integrity issue. Affected files: yaml.ts Signed-off-by: Quang Do --- src/pkg/utils/yaml.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/pkg/utils/yaml.ts b/src/pkg/utils/yaml.ts index 474ce7a8c..7224a9a9d 100644 --- a/src/pkg/utils/yaml.ts +++ b/src/pkg/utils/yaml.ts @@ -9,7 +9,7 @@ export function parseUserConfig(code: string): UserConfig | undefined { } const configs = config[1].trim().split(/[-]{3,}/); - const ret: UserConfig = {}; + const ret = Object.create(null) as UserConfig; const sortSet = new Set(); @@ -20,6 +20,10 @@ export function parseUserConfig(code: string): UserConfig | undefined { } // 验证是否符合分组规范:group -> config -> properties for (const [groupKey, groupValue] of Object.entries(obj)) { + if (["__proto__", "constructor", "prototype"].includes(groupKey)) { + throw new Error(`UserConfig group "${groupKey}" is not a valid object.`); + } + if (!groupValue || typeof groupValue !== "object") { // 如果分组值不是对象,说明不符合规范 throw new Error(`UserConfig group "${groupKey}" is not a valid object.`); From 9b20981cbb1d4d460f43cdfe2c52da249ce61f60 Mon Sep 17 00:00:00 2001 From: qdzsh Date: Wed, 10 Jun 2026 14:31:24 +0700 Subject: [PATCH 2/2] address review: use Reflect.has(Object.prototype) and fix error message - Reject any key inherited from Object.prototype (covers valueOf, toString, etc.) instead of a hardcoded __proto__/constructor/prototype list. - Correct the error message to reference the invalid key, not 'object'. --- src/pkg/utils/yaml.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/pkg/utils/yaml.ts b/src/pkg/utils/yaml.ts index 7224a9a9d..2e9377701 100644 --- a/src/pkg/utils/yaml.ts +++ b/src/pkg/utils/yaml.ts @@ -20,8 +20,10 @@ export function parseUserConfig(code: string): UserConfig | undefined { } // 验证是否符合分组规范:group -> config -> properties for (const [groupKey, groupValue] of Object.entries(obj)) { - if (["__proto__", "constructor", "prototype"].includes(groupKey)) { - throw new Error(`UserConfig group "${groupKey}" is not a valid object.`); + // Reject keys inherited from Object.prototype (e.g. __proto__, constructor, + // valueOf, toString) so untrusted userscript metadata can't pollute lookups. + if (Reflect.has(Object.prototype, groupKey)) { + throw new Error(`UserConfig key "${groupKey}" is not valid.`); } if (!groupValue || typeof groupValue !== "object") {