Semi-sandboxing Javascript eval
fundo: Estou trabalhando em uma estrutura / biblioteca a ser usada para um site específico em coordenação com o greasemonkey / userscripts. Essa estrutura / biblioteca permitirá o suporte a addons. A maneira como ele funciona é um addon que se registra com a biblioteca listando as páginas necessárias, recursos, ectera e a biblioteca esperará até que todos os critérios sejam atendidos para chamar o addon deload()
função.
O problema: Nesta lista de 'coisas necessárias' eu quero addon devs para poder especificar javascript (como string) para ser avaliado como um 'recurso necessário'. Por exemplo'document.getElementById("banana")'
. O que eu quero fazer é semi-sandbox a avaliação do "recurso necessário" para que a avaliação possa acessar a janela e os objetos DOM, mas não seja capaz de alterá-los diretamente. Eu também gostaria de fazer eval e evalJS inacessível a partir do sandbox.
Exemplos:
document.getElementById("banana")
-> válidodocument.getElementById("apple).id = "orange"
-> inválidowindow.grape
-> válidowindow.grape = 'potato'
-> inválido(someObj.applesCount > 0 ? 'some' : 'none')
-> válido
O que eu tenho até agora:
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;
}
Notas:
Este é um Greasemonkey / userscript. Eu não tenho acesso direto para alterar o site, ou é javascript.
A entrada parasafeEval()
pode ser qualquer javascript válido, seja uma consulta DOM ou avaliações simples, desde que não altere o objeto da janela ou o DOM.