仅执行服务器端数据时,在 javascript 中使用 eval 是否安全?

Is it safe to use eval in javascript when it only executes server-side data?

是的,有点像 this question, but the answer given by @apsillers is a super-answer as it points a new aspect of the problem that have not been told in the previous question. Another helpful SO question that helped me to undestand better what exactly are the eval() security concerns is that question

我在我的 javascript 代码中使用了 eval(),我想知道是否应该放弃它。

Principe :我有一个 ajax 调用,它初始化浏览器客户端和服务器之间的第一个连接。服务器运行 PHP。规则是:当客户端在请求中发送变量'init'时,在服务器端PHP获取必要脚本的内容,将每个脚本的内容作为一个新条目放入一个对象中(值为内容,名称是不带扩展名的文件名,对象是 PHP STD Class 的实例),将整个对象转换为 JSON(按照惯例)并发回所有内容。在客户端,当 httprequest 完成后,Javascript 获取对象并在其上做一个简单的 for ... in () 。

每次出现时,我都有两个选择:要么将内容连接到一个手工制作的脚本标签中,要么将其注入到 HTML 的 head 中页。或者我评估内容(我现在这样做)以便在不对 head 标记附加费用的情况下执行代码。主要是为了美观。

这是代码:

var xhr = null;

if (window.XMLHttpRequest || window.ActiveXObject) {
    ... //prepare the ajax request (initialize variable xhr)
}


var url = "index.php";
var params = "action=init";
xhr.open('POST', url, true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send(params);

xhr.onreadystatechange = function() {
       if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 0)) {
           var o = JSON.parse(xhr.responseText);


           for(s in o) eval(o[s]);


       }
}

我的问题:在这种情况下我应该绝对避免使用 eval 吗?或者它是否足够安全(因为只有管理员才能修改动态注入的脚本)?

eval 的安全规则是:用户永远不应 eval 由其他用户生成或修改的字符串。服务器创建的 eval 字符串是绝对安全的。毕竟,服务器正在提供页面的 实际代码 ,因此如果它选择将该代码作为 eval 字符串提供,则不一定存在安全问题。

就安全性而言,包含动态创建的 <script> 元素与调用 eval 元素基本上一样危险(或基本上一样安全)。唯一的区别是 <script> 代码将始终在全局范围内 运行,而 eval 可以在进行调用的词法范围内 运行,允许它访问来自其包含函数的变量。这可能需要也可能不需要,具体取决于您希望脚本访问的内容。

function f() {
    var a = 5;
    eval("alert(a);");
    // an injected <script> wouldn't have access to `a`
}

eval 的隐患是很难严格验证 eval 的内容从未被其他用户生成或修改过。在您的情况下,如果 Object.prototype 已提供任何可枚举的 属性(包含在您的 for..in 循环中),则 属性 的值将被 evaled :

Object.prototype.foo = "alert(1);";

您可以通过强制执行自己的 属性 检查来解决此问题:

for(var s in o) {
    if(o.hasOwnProperty(s)) {
        eval(o[s]);
    }
}

eval 也会导致显着的性能损失并产生无法优化的可变范围情况,但这不是安全问题。