将功能设置为默认值

问题描述 投票:2回答:1

背景:

我正在运行仅具有“ allow-scripts”许可的沙盒iframe。在沙盒中,脚本加载了用户提供的自定义js。现在,我想管理对诸如XMLHttpRequest之类的全局函数/对象的访问。目前,我通过以下代码实现了这一目标:

const CLEARED_WINDOW_SCOPE= {};
const scope = { /* Here goes the globals the script should have access too */};
const propertyNames = Object.getOwnPropertyNames(window);

for(let property of propertyNames){
    CLEARED_WINDOW_SCOPE[property] = undefined;
}

with(CLEARED_WINDOW_SCOPE){
    with(scope){
        (function (window, self, frames, globalThis){
            ${scriptContent}
        }).call(scope, scope, scope, scope, scope); 
    }
}

脚本执行以下操作:

  1. 创建所有窗口属性名称都设置为undefined的对象
  2. 创建具有用户也应具有的所有属性的对象
  3. 用两个with语句包装用户代码,第一个清除所有全局变量,第二个清除对定义的全局变量的访问权限
  4. scope作为this值调用的函数包装用户代码

到目前为止,一切正常,但例外。

问题:

我现在遇到的主要问题是,当用户定义这样的函数时:

function aFunction(){
   console.log(this);
}

他可以访问普通窗口对象,因为函数中的默认this值为窗口。

问题:

是否可以通过某种方式将函数的默认this值更改为周围示波器的this值。由于用户创建了脚本,因此我无法用aFunction.bind(scope)包装所有函数调用。还是有其他任何值可防止访问全局窗口对象?

javascript scope sandbox
1个回答
3
投票

是否可以将函数的默认this值更改为周围范围的this值。

否,但是您可以做第二件好事(?):将其设置为undefined。只是强制严格模式:

"use strict";

// User's code
(function (){
  console.log(this)
})();

而且,我不是JavaScript安全专家,但是由于原型污染等原因,JS沙箱是一个非常复杂的话题。

编辑:如注释中所述,CherryDT并不完全安全。例如,用户仍然可以通过使用<iframe>构造函数创建函数来访问window Function。另外,可以通过window <iframe>window)获得对主window.parent的引用。

可以将这种解决方案用于用户提供的代码(因为用户只能打开DevTools控制台并开始输入),但是请确保代码来自用户,而不是来自URL。搜索参数,例如。如果代码完全不可信,我建议使用window.parent之类的知名库。

© www.soinside.com 2019 - 2024. All rights reserved.