Wal*_*sby 136 javascript browser sandbox
我想知道是否可以在浏览器中运行JavaScript沙箱,以防止访问HTML页面中运行的JavaScript代码通常可用的功能.
例如,假设我想为最终用户提供一个JavaScript API,让他们定义在"有趣事件"发生时运行的事件处理程序,但我不希望这些用户访问该window对象的属性和功能.我能做到吗?
在最简单的情况下,假设我想阻止用户呼叫alert.我能想到的几种方法是:
window.alert全球重新定义.我不认为这是一种有效的方法,因为在页面中运行的其他代码(即用户在其事件处理程序中未编写的内容)可能想要使用alert.也许服务器处理用户定义的函数然后生成要在客户端上执行的回调的解决方案可行吗?即使这种方法有效,是否有更好的方法来解决这个问题?
Dar*_*con 54
Google Caja是一个源到源的翻译器,"允许您将不受信任的第三方HTML和JavaScript内嵌到您的页面中,并且仍然是安全的."
Sim*_*hke 32
ADsafe可以将访客代码(例如第三方脚本广告或小部件)放在任何网页上.ADsafe定义了一个强大的JavaScript子集,允许访客代码执行有价值的交互,同时防止恶意或意外损坏或入侵.ADsafe子集可以通过JSLint等工具进行机械验证,因此无需人工检查即可查看访客代码的安全性.ADsafe子集还实施了良好的编码实践,增加了访客代码正确运行的可能性.
您可以通过查看项目的GitHub存储库中的template.html和template.js文件来查看如何使用ADsafe的示例.
Eli*_*rey 23
我创建了一个名为jsandbox的沙盒库,它使用Web worker对沙盒进行评估.它还有一个输入方法,用于显式提供它本来无法获得的沙盒代码数据.
以下是API的示例:
jsandbox
.eval({
code : "x=1;Math.round(Math.pow(input, ++x))",
input : 36.565010597564445,
callback: function(n) {
console.log("number: ", n); // number: 1337
}
}).eval({
code : "][];.]\\ (*# ($(! ~",
onerror: function(ex) {
console.log("syntax error: ", ex); // syntax error: [error object]
}
}).eval({
code : '"foo"+input',
input : "bar",
callback: function(str) {
console.log("string: ", str); // string: foobar
}
}).eval({
code : "({q:1, w:2})",
callback: function(obj) {
console.log("object: ", obj); // object: object q=1 w=2
}
}).eval({
code : "[1, 2, 3].concat(input)",
input : [4, 5, 6],
callback: function(arr) {
console.log("array: ", arr); // array: [1, 2, 3, 4, 5, 6]
}
}).eval({
code : "function x(z){this.y=z;};new x(input)",
input : 4,
callback: function(x) {
console.log("new x: ", x); // new x: object y=4
}
});
Run Code Online (Sandbox Code Playgroud)
RyanOHara 的网络工作者沙箱代码的改进版本,在单个文件中(不需要额外的eval.js文件)。
function safeEval(untrustedCode)
{
return new Promise(function (resolve, reject)
{
var blobURL = URL.createObjectURL(new Blob([
"(",
function ()
{
var _postMessage = postMessage;
var _addEventListener = addEventListener;
(function (obj)
{
"use strict";
var current = obj;
var keepProperties =
[
// Required
'Object', 'Function', 'Infinity', 'NaN', 'undefined', 'caches', 'TEMPORARY', 'PERSISTENT',
// Optional, but trivial to get back
'Array', 'Boolean', 'Number', 'String', 'Symbol',
// Optional
'Map', 'Math', 'Set',
];
do
{
Object.getOwnPropertyNames(current).forEach(function (name)
{
if (keepProperties.indexOf(name) === -1)
{
delete current[name];
}
});
current = Object.getPrototypeOf(current);
}
while (current !== Object.prototype)
;
})(this);
_addEventListener("message", function (e)
{
var f = new Function("", "return (" + e.data + "\n);");
_postMessage(f());
});
}.toString(),
")()"],
{type: "application/javascript"}));
var worker = new Worker(blobURL);
URL.revokeObjectURL(blobURL);
worker.onmessage = function (evt)
{
worker.terminate();
resolve(evt.data);
};
worker.onerror = function (evt)
{
reject(new Error(evt.message));
};
worker.postMessage(untrustedCode);
setTimeout(function ()
{
worker.terminate();
reject(new Error('The worker timed out.'));
}, 1000);
});
}
Run Code Online (Sandbox Code Playgroud)
测试一下:
https://jsfiddle.net/kp0cq6yw/
var promise = safeEval("1+2+3");
promise.then(function (result) {
alert(result);
});
Run Code Online (Sandbox Code Playgroud)
它应该输出6(在 Chrome 和 Firefox 中测试)。
所有浏览器供应商和 HTML5 规范都在努力实现一个实际的沙箱属性,以允许沙箱 iframe —— 但它仍然限于 iframe 粒度。
一般来说,没有任何程度的正则表达式等可以安全地清理任意用户提供的 JavaScript,因为它退化为停机问题:-/
正如其他响应中所提到的,它足以将沙盒iframe中的代码(不将其发送到服务器端)并与消息进行通信.我建议看看我创建的一个小型库,主要是因为需要为不受信任的代码提供一些API,就像问题中所描述的那样:有机会将特定的函数集导出到沙箱中不受信任的代码运行.还有一个演示,它执行用户在沙箱中提交的代码:
http://asvd.github.io/jailed/demos/web/console/
Joh*_*kin -6
您可以将用户的代码包装在一个函数中,该函数将禁止的对象重新定义为参数——这些将在undefined调用时出现:
(function (alert) {
alert ("uh oh!"); // User code
}) ();
Run Code Online (Sandbox Code Playgroud)
当然,聪明的攻击者可以通过检查 JavaScript DOM 并找到包含窗口引用的非重写对象来绕过这个问题。
另一个想法是使用JSLint等工具扫描用户的代码。确保将其设置为没有预设变量(或者:只有您想要的变量),然后如果设置或访问任何全局变量,则不要使用用户的脚本。同样,它可能容易受到遍历 DOM 的影响——用户可以使用文字构造的对象可能具有对窗口对象的隐式引用,可以通过访问该窗口对象来逃避沙箱。
| 归档时间: |
|
| 查看次数: |
44615 次 |
| 最近记录: |