W dążeniu do posiadania interfejsu zdolnego do uruchamiania dowolnego kodu javascript wewnątrz przeglądarki, bez dziury w bezpieczeństwie wielkości typowego żartu jo-mama, Esailija proponowanego przy użyciu Web Workers. Działają w środowisku pół-piaskownicy (brak dostępu do DOM i już wewnątrz przeglądarki) i mogą zostać zabite, aby użytkownik nie mógł umieścić ich w nieskończonej pętli.Uczynienie WebWorkers bezpiecznym środowiskiem
Oto przykład on wychowany: http://tuohiniemi.fi/~runeli/petka/workertest.html (otwórz konsolę)
jsfiddle (tylko Google chrome)
Teraz wydaje się to dobrym rozwiązaniem; jednak czy jest to kompletny (lub zbliża się kompletny)? Czy brakuje czegoś oczywistego?
Cała rzecz (jak to podłączyć do bot) można znaleźć na github: worker, evaluator
główny:
workercode = "worker.js";
function makeWorkerExecuteSomeCode(code, callback) {
var timeout;
code = code + "";
var worker = new Worker(workercode);
worker.addEventListener("message", function(event) {
clearTimeout(timeout);
callback(event.data);
});
worker.postMessage({
code: code
});
timeout = window.setTimeout(function() {
callback("Maximum execution time exceeded");
worker.terminate();
}, 1000);
}
makeWorkerExecuteSomeCode('5 + 5', function(answer){
console.log(answer);
});
makeWorkerExecuteSomeCode('while(true);', function(answer){
console.log(answer);
});
var kertoma = 'function kertoma(n){return n === 1 ? 1 : n * kertoma(n-1)}; kertoma(15);';
makeWorkerExecuteSomeCode(kertoma, function(answer){
console.log(answer);
});
pracownika:
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);
};
Czy nadal nie mogą wysyłać żądań AJAX? – SLaks
@SLaks Pracownik ma XHR ustawiony na 'null' – Esailija
@SLaks Możesz samodzielnie usunąć kilka niepewnych właściwości, jak pokazano w przykładzie. – Zirak