Javascript 让网络工作者有一个安全的环境
为了寻求一个能够在浏览器中运行任意javascript代码的界面,而不存在典型yo mama笑话大小的安全漏洞,建议使用。它们在一个半沙盒环境中运行(没有DOM访问,并且已经在浏览器中),并且可以被杀死,因此用户不能将它们放入无限循环中 他举了一个例子:(打开控制台) (仅限谷歌浏览器) 现在,这似乎是一个很好的解决方案;然而,它是一个完整的(或接近完整的)吗?有什么明显的遗漏吗 整个东西(连接到机器人)都可以在github上找到: 主要内容: 工人:Javascript 让网络工作者有一个安全的环境,javascript,web-worker,Javascript,Web Worker,为了寻求一个能够在浏览器中运行任意javascript代码的界面,而不存在典型yo mama笑话大小的安全漏洞,建议使用。它们在一个半沙盒环境中运行(没有DOM访问,并且已经在浏览器中),并且可以被杀死,因此用户不能将它们放入无限循环中 他举了一个例子:(打开控制台) (仅限谷歌浏览器) 现在,这似乎是一个很好的解决方案;然而,它是一个完整的(或接近完整的)吗?有什么明显的遗漏吗 整个东西(连接到机器人)都可以在github上找到: 主要内容: 工人: var global = this; /
var global = this;
/* Could possibly create some helper functions here so they are always available when executing code in chat?*/
/* Most extra functions could be possibly unsafe */
var wl = {
"self": 1,
"onmessage": 1,
"postMessage": 1,
"global": 1,
"wl": 1,
"eval": 1,
"Array": 1,
"Boolean": 1,
"Date": 1,
"Function": 1,
"Number" : 1,
"Object": 1,
"RegExp": 1,
"String": 1,
"Error": 1,
"EvalError": 1,
"RangeError": 1,
"ReferenceError": 1,
"SyntaxError": 1,
"TypeError": 1,
"URIError": 1,
"decodeURI": 1,
"decodeURIComponent": 1,
"encodeURI": 1,
"encodeURIComponent": 1,
"isFinite": 1,
"isNaN": 1,
"parseFloat": 1,
"parseInt": 1,
"Infinity": 1,
"JSON": 1,
"Math": 1,
"NaN": 1,
"undefined": 1
};
Object.getOwnPropertyNames( global ).forEach( function( prop ) {
if( !wl.hasOwnProperty( prop ) ) {
Object.defineProperty( global, prop, {
get : function() {
throw new Error( "Security Exception: cannot access "+prop);
return 1;
},
configurable : false
});
}
});
Object.getOwnPropertyNames( global.__proto__ ).forEach( function( prop ) {
if( !wl.hasOwnProperty( prop ) ) {
Object.defineProperty( global.__proto__, prop, {
get : function() {
throw new Error( "Security Exception: cannot access "+prop);
return 1;
},
configurable : false
});
}
});
onmessage = function( event ) {
"use strict";
var code = event.data.code;
var result;
try {
result = eval( '"use strict";\n'+code );
}
catch(e){
result = e.toString();
}
postMessage( "(" + typeof result + ")" + " " + result );
};
当前代码(如下所列)已经在Stackoverflow javascript聊天室中使用了一段时间
到目前为止,最棘手的问题是数组(5000000000)。join(“adasdadadasd”)
立即使一些
当我运行代码执行器bot时,浏览器选项卡为我显示。MonkeypatchingArray.prototype.join
似乎已经修复了这个问题和最大问题
对于任何其他占用内存或使浏览器崩溃的尝试,50ms的执行时间都有效
var global = this;
/* Could possibly create some helper functions here so they are always available when executing code in chat?*/
/* Most extra functions could be possibly unsafe */
var wl = {
"self": 1,
"onmessage": 1,
"postMessage": 1,
"global": 1,
"wl": 1,
"eval": 1,
"Array": 1,
"Boolean": 1,
"Date": 1,
"Function": 1,
"Number" : 1,
"Object": 1,
"RegExp": 1,
"String": 1,
"Error": 1,
"EvalError": 1,
"RangeError": 1,
"ReferenceError": 1,
"SyntaxError": 1,
"TypeError": 1,
"URIError": 1,
"decodeURI": 1,
"decodeURIComponent": 1,
"encodeURI": 1,
"encodeURIComponent": 1,
"isFinite": 1,
"isNaN": 1,
"parseFloat": 1,
"parseInt": 1,
"Infinity": 1,
"JSON": 1,
"Math": 1,
"NaN": 1,
"undefined": 1
};
Object.getOwnPropertyNames( global ).forEach( function( prop ) {
if( !wl.hasOwnProperty( prop ) ) {
Object.defineProperty( global, prop, {
get : function() {
throw "Security Exception: cannot access "+prop;
return 1;
},
configurable : false
});
}
});
Object.getOwnPropertyNames( global.__proto__ ).forEach( function( prop ) {
if( !wl.hasOwnProperty( prop ) ) {
Object.defineProperty( global.__proto__, prop, {
get : function() {
throw "Security Exception: cannot access "+prop;
return 1;
},
configurable : false
});
}
});
Object.defineProperty( Array.prototype, "join", {
writable: false,
configurable: false,
enumerable: false,
value: function(old){
return function(arg){
if( this.length > 500 || (arg && arg.length > 500 ) ) {
throw "Exception: too many items";
}
return old.apply( this, arguments );
};
}(Array.prototype.join)
});
(function(){
var cvalues = [];
var console = {
log: function(){
cvalues = cvalues.concat( [].slice.call( arguments ) );
}
};
function objToResult( obj ) {
var result = obj;
switch( typeof result ) {
case "string":
return '"' + result + '"';
break;
case "number":
case "boolean":
case "undefined":
case "null":
case "function":
return result + "";
break;
case "object":
if( !result ) {
return "null";
}
else if( result.constructor === Object || result.constructor === Array ) {
var type = ({}).toString.call( result );
var stringified;
try {
stringified = JSON.stringify(result);
}
catch(e) {
return ""+e;
}
return type + " " + stringified;
}
else {
return ({}).toString.call( result );
}
break;
}
}
onmessage = function( event ) {
"use strict";
var code = event.data.code;
var result;
try {
result = eval( '"use strict";\n'+code );
}
catch(e) {
postMessage( e.toString() );
return;
}
result = objToResult( result );
if( cvalues && cvalues.length ) {
result = result + cvalues.map( function( value, index ) {
return "Console log "+(index+1)+":" + objToResult(value);
}).join(" ");
}
postMessage( (""+result).substr(0,400) );
};
})();
问题中显示的当前代码(2014-11-07)尽管表面上不允许访问XMLHttpRequest
(因为它未列入白名单),但仍然允许代码访问它
如果我将代码放在网页和工作者组合中的问题(或接受的答案)中,并在Chrome 38上执行以下代码:
makeWorkerExecuteSomeCode('event.target.XMLHttpRequest', function (answer) { console.log( answer ); });
makeWorkerExecuteSomeCode(
'var c = self.__proto__.__proto__.__lookupGetter__("console").call(self); c.log("FOO");',
function (answer) { console.log(answer) });
结果是:
function XMLHttpRequest() { [native code] }
但是,它在FF中不起作用。Chrome中的Bug
我还发现了另一件事,但似乎并没有深入到rabit漏洞的深处,那就是恢复console.log
。这适用于FF 31,但不适用于Chrome 38:
makeWorkerExecuteSomeCode('event.target.XMLHttpRequest', function (answer) { console.log( answer ); });
makeWorkerExecuteSomeCode(
'var c = self.__proto__.__proto__.__lookupGetter__("console").call(self); c.log("FOO");',
function (answer) { console.log(answer) });
这会将“FOO”
记录到控制台,而不会通过web worker提供的假控制台.log
。上面的代码使用了self
,它可以被列入黑名单(通过将其从白名单中删除),但是这个和全局
也可以使用。我发现在FF和Chrome上尝试黑名单global
失败:工人死于错误
注意:Chrome拒绝黑名单Intl
,因此必须将其添加到白名单中才能运行代码。他们是否仍然能够发送AJAX请求?@SLaks worker将XHR设置为null
如果删除
本机/主机对象,它将恢复为原始状态<代码>“删除XMLHttpRequest;XMLHttpRequest;”
将返回原始的XMLHttpRequest对象。一定有办法解决这个问题:你有一个不安全的函数黑名单。看起来不太好。如果新的标准或浏览器定义了新的不安全函数呢?作为一个偏执狂,我会添加一些运行时测试,您的方法实际上会阻止工作系统上的某些东西。否则,看起来没问题,但我不是专家。为什么数学和解析*函数被禁用了?@Domi为什么你认为它们被禁用了disabled@Domi我认为你误解了——这是一种白名单方法。未列出的内容是不允许的,而只允许列出的内容。白名单更好,因为它在实现新的API时不需要更新。对于未来的API,您如何知道这一点?:-)但我现在已经检查过了,Object.defineProperty
将抛出并阻止设置onmessage
处理程序。@Domi*超时和*间隔函数已列出(我使用的是版本33.0.1750.152)关于Chrome 38中的漏洞非常好,但这很容易填充:只需在onmessage
中的try/catch
周围放置一个闭包,并用var事件重新定义事件
代码>在闭包中。那么有什么真正的解决方案吗?