From 0d3de1ef736fadfe17cc1dbcafe50035b3c73755 Mon Sep 17 00:00:00 2001 From: IceCola <739201322@qq.com> Date: Fri, 31 May 2024 16:34:54 +0800 Subject: [PATCH] =?UTF-8?q?=E5=86=8D=E6=AC=A1=E5=85=B3=E9=97=AD=E5=85=A8?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E6=B2=99=E7=9B=92=EF=BC=9B=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E5=8F=B0=E7=9A=84=E8=AF=AD=E6=B3=95=E9=97=AE?= =?UTF-8?q?=E9=A2=98=EF=BC=9B=E4=BF=AE=E5=A4=8D=E4=B8=80=E4=B8=AA=E9=80=9A?= =?UTF-8?q?=E8=BF=87=E9=94=99=E8=AF=AF=E9=80=83=E9=80=B8=E7=9A=84=E6=BC=8F?= =?UTF-8?q?=E6=B4=9E=EF=BC=9B=E4=BF=AE=E5=A4=8D=E6=B2=A1=E6=9C=89=E4=BC=A0?= =?UTF-8?q?=E9=80=92this=E5=88=B0=E9=97=AD=E5=8C=85=E5=87=BD=E6=95=B0?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- noname/util/sandbox.js | 53 ++++++++++++++++++++++++++++++++++++----- noname/util/security.js | 2 +- 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/noname/util/sandbox.js b/noname/util/sandbox.js index 33deed546..e67233f6f 100644 --- a/noname/util/sandbox.js +++ b/noname/util/sandbox.js @@ -2300,10 +2300,18 @@ class Marshal { const errorCtor = target.constructor; const mappedCtor = Globals.mapTo(errorCtor, sourceDomain, targetDomain); + // // 立即报告错误,而不是通过封送报错 + // const window = Domain.topDomain[SandboxExposer](SandboxSignal_GetWindow); + // window.onunhandledrejection && window.onunhandledrejection({ promise: Promise.reject(target) }); + if (mappedCtor) { const newError = new mappedCtor(); - Object.defineProperties(newError, - Object.getOwnPropertyDescriptors(target)); + const stack = String(target.stack); + Reflect.defineProperty(newError, 'stack', { + get: () => () => stack, + set: () => { }, + configurable: false, + }); return newError; } } @@ -3322,8 +3330,13 @@ class Sandbox { while (code.endsWith(";")) code = code.slice(0, -1); - if (!/[;\n\r]$/.test(code)) - code = `return (${code})`; + if (!/[;\n\r]$/.test(code)) { + const newCode = `return (${code})`; + try { + new Function(newCode); + code = newCode; + } catch (e) { } + } return thiz.exec(code); } @@ -3555,6 +3568,7 @@ class Sandbox { // 进行语法检查,防止注入 new thiz.#domainFunction(code); + const passThis = !("this" in context); const executingScope = Sandbox.#executingScope[Sandbox.#executingScope.length - 1]; const scope = inheritScope && executingScope || thiz.#scope; const contextName = Sandbox.#makeName("_", scope); @@ -3617,7 +3631,7 @@ class Sandbox { // 构建陷入的沙盒闭包 // 同时对返回值进行封送 - return ((/** @type {any} */ ...args) => { + return /** @this {any} */ function (/** @type {any} */ ...args) { const prevDomain = Domain.current; const domainAction = () => { // 指定执行域 @@ -3625,11 +3639,38 @@ class Sandbox { Sandbox.#executingScope.push(scope); try { + // 传递 `this`、以及函数参数 + if (passThis) + context.this = Marshal[SandboxExposer2] + (SandboxSignal_Marshal, this, domain); argumentList = Marshal[SandboxExposer2] (SandboxSignal_MarshalArray, args, domain); + + // 调用闭包函数 const result = raw.call(null, intercepter); + + // 封送返回结果 return Marshal[SandboxExposer2] (SandboxSignal_Marshal, result, prevDomain); + // } catch (e) { + // // 立即报告错误 + // const window = Domain.topDomain[SandboxExposer](SandboxSignal_GetWindow); + // // @ts-ignore + // const line = String(e.stack).split("\n")[1]; + // const match = /:(\d+):\d+\)/.exec(line); + // if (match) { + // const index = parseInt(match[1]) - 5; + // const lines = code.split("\n"); + // let codeView = ""; + // for (let i = index - 4; i < index + 5; i++) { + // if (i < 0 || i >= lines.length) + // continue; + // codeView += `${i + 1}|${i == index ? "⚠️" : " "}${lines[i]}\n`; + // } + // // @ts-ignore + // window.alert(`沙盒内出现错误:\n----------\n${codeView}\n----------\n${String(e.stack)}`); + // } + // throw e; } finally { Sandbox.#executingScope.pop(); } @@ -3640,7 +3681,7 @@ class Sandbox { return Marshal[SandboxExposer2] (SandboxSignal_TrapDomain, domain, domainAction); - }).bind(null); // 编译函数不应该发送 + }; } /** diff --git a/noname/util/security.js b/noname/util/security.js index b98da23a8..b24e4177e 100644 --- a/noname/util/security.js +++ b/noname/util/security.js @@ -2,7 +2,7 @@ // 但沙盒不会也没有办法维护恶意服务器/房主对于游戏规则的破坏,请玩家尽量选择官方或其他安全的服务器,同时选择一个受信任的玩家作为房主 // 是否强制所有模式下使用沙盒 -const SANDBOX_FORCED = true; +const SANDBOX_FORCED = false; // 是否启用自动测试 const SANDBOX_AUTOTEST = false; // 是否禁用自动测试延迟