设置函数默认值
Set function default this value
背景:
我是 运行 一个只有 "allow-scripts" 权限的沙盒 iframe。在沙箱中,脚本加载了用户提供的自定义 js。现在我想像 XMLHttpRequest 一样管理对全局 functions/objects 的访问。目前我通过以下代码实现了这一点:
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);
}
}
该脚本执行以下操作:
- 创建所有 window 属性 名称未定义的对象
- 使用用户也应有权访问的所有属性创建对象
- 用两个
with
语句包装用户代码,第一个清除所有全局变量,第二个获取定义的全局变量
- 用
scope
作为 this
值 调用的函数包装用户代码
到目前为止,一切正常,一切正常。
问题:
我现在遇到的主要问题是,当用户定义这样的函数时:
function aFunction(){
console.log(this);
}
他可以访问正常的 window 对象,因为函数中的默认 this
值是 window.
问题:
是否可以通过某种方式将函数的默认 this
值更改为周围作用域的 this
值。由于用户创建了脚本,我无法用 aFunction.bind(scope)
包装所有函数调用。或者是否有任何其他值可以防止访问全局 window 对象?
Is it somehow possible to change the default this value of a function to the this value of the surrounding scope.
不,但您可以做次优(?)的事情:将其设置为 undefined
。强制严格模式:
"use strict";
// User's code
(function (){
console.log(this)
})();
此外,我不是 JavaScript 安全专家,但 JS 沙箱是一个非常复杂的主题,因为原型污染等问题。
编辑: 为 CherryDT noted in the comments, this method is not completely secure. Users can still access the <iframe>
window
by creating a function with the Function
constructor, for example. Also, a reference to the main window
can be obtained through the <iframe>
window
(window.parent
).
将此解决方案用于 用户提供的 代码可能没问题(因为用户只需打开 DevTools 控制台并开始输入),但要确保代码来自 [=例如,36=]用户 而不是来自 URL 搜索参数。如果代码完全不受信任,我建议使用像 Google Caja.
这样的知名库
背景:
我是 运行 一个只有 "allow-scripts" 权限的沙盒 iframe。在沙箱中,脚本加载了用户提供的自定义 js。现在我想像 XMLHttpRequest 一样管理对全局 functions/objects 的访问。目前我通过以下代码实现了这一点:
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);
}
}
该脚本执行以下操作:
- 创建所有 window 属性 名称未定义的对象
- 使用用户也应有权访问的所有属性创建对象
- 用两个
with
语句包装用户代码,第一个清除所有全局变量,第二个获取定义的全局变量 - 用
scope
作为this
值 调用的函数包装用户代码
到目前为止,一切正常,一切正常。
问题:
我现在遇到的主要问题是,当用户定义这样的函数时:
function aFunction(){
console.log(this);
}
他可以访问正常的 window 对象,因为函数中的默认 this
值是 window.
问题:
是否可以通过某种方式将函数的默认 this
值更改为周围作用域的 this
值。由于用户创建了脚本,我无法用 aFunction.bind(scope)
包装所有函数调用。或者是否有任何其他值可以防止访问全局 window 对象?
Is it somehow possible to change the default this value of a function to the this value of the surrounding scope.
不,但您可以做次优(?)的事情:将其设置为 undefined
。强制严格模式:
"use strict";
// User's code
(function (){
console.log(this)
})();
此外,我不是 JavaScript 安全专家,但 JS 沙箱是一个非常复杂的主题,因为原型污染等问题。
编辑: 为 CherryDT noted in the comments, this method is not completely secure. Users can still access the <iframe>
window
by creating a function with the Function
constructor, for example. Also, a reference to the main window
can be obtained through the <iframe>
window
(window.parent
).
将此解决方案用于 用户提供的 代码可能没问题(因为用户只需打开 DevTools 控制台并开始输入),但要确保代码来自 [=例如,36=]用户 而不是来自 URL 搜索参数。如果代码完全不受信任,我建议使用像 Google Caja.
这样的知名库