将eval()限制在一个狭窄的范围内

我有一个JavaScript文件,读取另一个文件,其中可能包含需要eval() - ed的JavaScript片段。 脚本片段应该符合javascript的严格子集,这限制了他们可以做的事情以及他们可以更改哪些变量,但是我想知道是否有某种方法可以通过阻止eval在全局范围中看到变量来强制执行此操作。 如下所示:

function safeEval( fragment )
{
    var localVariable = g_Variable;

    {
        // do magic scoping here so that the eval fragment can see localVariable
        // but not g_Variable or anything else outside function scope

        eval( fragment );
    }
}

实际的代码不需要看起来像这样 - 我可以使用任何和所有关闭的怪异技巧,但我确实想知道这是否可能。


简答 :不。如果它在全球范围内,它可用于任何事情。

长的回答 :如果你对真正想要阅读或混淆执行环境的不可信代码进行eval() ,那么就搞砸了。 但是,如果您拥有并信任所有正在执行的代码,包括eval() ,您可以通过覆盖执行上下文来伪造它:

function maskedEval(scr)
{
    // set up an object to serve as the context for the code
    // being evaluated. 
    var mask = {};
    // mask global properties 
    for (p in this)
        mask[p] = undefined;

    // execute script in private context
    (new Function( "with(this) { " + scr + "}")).call(mask);
}

同样,我必须强调:

这只会用来屏蔽受信任的代码与执行它的上下文。 如果你不相信代码,不要eval()它(或者将它传递给新的Function() ,或者以任何其他方式使用它,就像eval() )。


你不能限制eval的范围

顺便看到这篇文章

可能还有其他一些方法可以完成您在事物的宏伟计划中完成的任务,但您无法以任何方式限制eval的范围。 您可能可以隐藏某些变量作为JavaScript中的私有变量,但我不认为这是你要做的。


这是一个想法。 如果你使用了一个静态分析器(例如你可以用esprima构建的东西)来确定评估代码使用哪些外部变量,并为它们加上别名。 通过“外部代码”我的意思是eval'd代码使用的变量,但没有声明。 这是一个例子:

eval(safeEval(
     "var x = window.theX;"
    +"y = Math.random();"
    +"eval('window.z = 500;');"))

其中safeEval返回用禁止访问外部变量的上下文修改的javascript字符串:

";(function(y, Math, window) {"
  +"var x = window.theX;"
  +"y = Math.random();"
  +"eval(safeEval('window.z = 500;');"
"})();"

现在有几件事你可以用这个做:

  • 您可以确保eval'd代码无法读取外部变量的值,也不会写入(通过传递undefined作为函数参数或不传递参数)。 或者,您可以简单地在变量被不安全访问的情况下抛出异常。
  • 您还要确保由eval创建的变量不会影响周围的范围
  • 你可以允许eval通过在闭包之外声明这些变量而不是作为函数参数来在周围范围中创建变量
  • 您可以通过复制外部变量的值并将它们用作函数的参数来允许只读访问
  • 您可以通过告诉safeEval不要别名这些特定名称来允许读写访问特定变量
  • 您可以检测到eval没有修改特定变量并允许它被自动排除为别名的情况(例如,在这种情况下,数学不会被修改)
  • 您可以通过传递可能与周围环境不同的参数值来给eval一个运行环境
  • 您可以通过从函数返回函数参数来捕获上下文更改,以便您可以在eval外部检查它们。
  • 请注意,使用eval是一种特殊情况,因为从本质eval(safeEval(...)) ,它实际上不能包含在另一个函数中(这就是为什么我们必须执行eval(safeEval(...)) )。

    当然,完成所有这些工作可能会减慢你的代码速度,但肯定有一些地方不会影响命中。 希望这可以帮助某人。 如果有人创造了一个概念证明,我很乐意在这里看到一个链接。 )

    链接地址: http://www.djcxy.com/p/51677.html

    上一篇: Restricting eval() to a narrow scope

    下一篇: What is the (function() { } )() construct in JavaScript?