From 4bb6cd679d700399a2f0960765ba9de49c61b9dc Mon Sep 17 00:00:00 2001 From: mtvpls Date: Sun, 22 Mar 2026 00:52:28 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=84=9A=E6=9C=AC=E5=AF=BC?= =?UTF-8?q?=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/lib/source-script.ts | 41 +++++++++------------------------------- 1 file changed, 9 insertions(+), 32 deletions(-) diff --git a/src/lib/source-script.ts b/src/lib/source-script.ts index 3fe944d..80383d8 100644 --- a/src/lib/source-script.ts +++ b/src/lib/source-script.ts @@ -8,6 +8,10 @@ import { db } from '@/lib/db'; const SOURCE_SCRIPT_REGISTRY_KEY = 'source-script:registry'; const DEFAULT_TIMEOUT_MS = 20000; +// 绕过 webpack 静态分析,获取真正的 Node.js require +// eslint-disable-next-line no-eval +const _nodeRequire = eval('require') as NodeRequire; + // ---- 内存缓存 ---- let _registryCache: { data: SourceScriptRegistry; ts: number } | null = null; const REGISTRY_CACHE_TTL_MS = 5_000; @@ -188,24 +192,6 @@ function assertScriptKey(key: string) { } } -function assertSafeCode(code: string) { - const blockedPatterns = [ - /\brequire\s*\(/, - /\bprocess\./, - /\bchild_process\b/, - /\bfs\b/, - /\bimport\s*\(/, - /\beval\s*\(/, - /\bnew\s+Function\b/, - ]; - - for (const pattern of blockedPatterns) { - if (pattern.test(code)) { - throw new Error(`脚本包含不允许的用法: ${pattern}`); - } - } -} - function createLogCollector() { const logs: string[] = []; @@ -313,17 +299,10 @@ function createUtils() { } function createScriptFactory(code: string) { - assertSafeCode(code); - return new Function( - `"use strict"; -const process = undefined; -const require = undefined; -const module = undefined; -const exports = undefined; -const fetch = undefined; -${code}` - ) as () => any; + 'require', + `"use strict";\n${code}` + ) as (req: NodeRequire) => any; } async function createScriptContext(script: SourceScriptRecord, configValues?: Record) { @@ -462,7 +441,7 @@ function getOrCompileScript(script: SourceScriptRecord) { if (cached) return cached; const factory = createScriptFactory(script.code); - const compiled = normalizeScript(factory()); + const compiled = normalizeScript(factory(_nodeRequire)); if (_compiledCache.size >= MAX_COMPILED_CACHE_SIZE) { const firstKey = _compiledCache.keys().next().value; @@ -550,7 +529,6 @@ export async function saveSourceScript(input: { enabled?: boolean; }) { assertScriptKey(input.key); - assertSafeCode(input.code); const registry = await loadRegistry(); const now = Date.now(); @@ -602,7 +580,6 @@ export async function importSourceScripts(items: SourceScriptImportItem[]) { } assertScriptKey(item.key); - assertSafeCode(item.code); const existing = registry.items.find((record) => record.key === item.key); @@ -682,7 +659,7 @@ export async function testSourceScript(input: { }; const factory = createScriptFactory(input.code); - const compiled = normalizeScript(factory()); + const compiled = normalizeScript(factory(_nodeRequire)); const hook = compiled[input.hook]; if (typeof hook !== 'function') { throw new Error(`脚本未实现 ${input.hook} hook`);