【发布时间】:2012-09-02 07:31:42
【问题描述】:
背景:我正在开发一个框架/库,用于与greasemonkey/userscripts 协调的特定站点。这个框架/库将允许插件支持。它的工作方式是在库中注册一个插件,列出所需的页面、资源等,并且该库将等到满足所有条件后才调用插件的 load() 函数。
问题:在这个“必需的东西”列表中,我希望插件开发人员能够指定要评估为“必需资源”的 javascript(作为字符串)。例如'document.getElementById("banana")'。我想要做的是半沙箱评估“所需资源”,因此评估可以访问窗口和 DOM 对象,但不能直接更改它们。我还想让 eval 和 evalJS 无法从沙箱中访问。
示例:
-
document.getElementById("banana")-> 有效 -
document.getElementById("apple).id = "orange"-> 无效 -
window.grape-> 有效 -
window.grape = 'potato'-> 无效 -
(someObj.applesCount > 0 ? 'some' : 'none')-> 有效
我目前所拥有的:
function safeEval(input) {
// Remove eval and evalJS from the window:
var e = [window.eval, window.evalJS], a;
window.eval = function(){};
window.evalJS = function(){};
try {
/* More sanition needed before being passed to eval */
// Eval the input, stuffed into an annonomous function
// so the code to be evalued can not access the stored
// eval functions:
a = (e[0])("(function(){return "+input+"}())");
} catch(ex){}
// Return eval and evalJS to the window:
window.eval = e[0];
window.evalJS = e[1];
// Return the eval'd result
return a;
}
注意事项:
这是一个 Greasemonkey/用户脚本。我没有直接访问权限来更改网站,或者它是 javascript。safeEval() 的输入可以是任何有效的 javascript,可以是 DOM 查询,也可以是简单的求值,只要它不改变窗口对象或 DOM。
【问题讨论】:
-
如果是我的网络服务器从第三方提取代码,Caja 就很好。但是greasemonkey/userscripts 是客户端的,并且在已经装满它们的站点上需要另一个库/小部件并不是我愿意接受这个问题的解决方案。 (我很抱歉,如果这突然出现,我不是这个意思)
-
看起来 Caja 从 Greasemonkey 使用起来相当简单:一个
@require指令和一些对其 API 的 GM_xhr 调用。不过,不确定 Caja 是否符合您的要求。 -
Chrome 和 Opera 的用户脚本支持不强制使用 @require 标签,遗憾的是
-
关于深度克隆
window和document的想法?这样,属性将是可更改的,但您可以在之后恢复原始 DOM。不过,可能会影响性能。
标签: javascript eval greasemonkey sandbox