假设我收到了对JavaScript和HTML混合使用的AJAX数据加载请求的响应,例如:

<script>window.alert('Hello World!');</script>
<p>This is a paragraph. Lorem ipsum dolor sit amet...</p>

如果我只是将该响应放入div或其他容器中,则脚本不会自动执行。我知道这可以通过eval()函数完成(如下例所示),但是eval是邪恶的,那么我该如何正确地做到这一点? 注意:我没有使用jQuery。

以下是AJAX加载程序的示例:
function Load(id,url){
    var ajax=new XMLHttpRequest();
    ajax.onreadystatechange=function(){
        if(ajax.readyState!=4)return;
        var obj=document.getElementById(id);
        if(!obj)return;
        obj.innerHTML=ajax.responseText;

        // load any scripts
        var s=obj.getElementsByTagName('script');
        for(var i=0;i<s.length;++i)window.eval(s[i].innerHTML); // <-- bad
    }
    ajax.open("GET",url,true);
    ajax.send(null);
}

最佳答案

请注意,您正在从用户那里获取输入,并在您网站上的脚本上下文中运行它。因此,脚本可以执行在您的浏览器/域上运行的JavaScript能够执行的任何操作(包括cookie窃取,XSS,恶意驱动器等)。

实际上,减轻风险的唯一措施就是不要eval()用户提供的内容。我建议考虑以下替代方法:

  • 使用iframe作为运行用户脚本的环境:
    http://dean.edwards.name/weblog/2006/11/sandbox/
  • 使用Caja。它使网站能够安全地嵌入第三方的DHTML Web应用程序,并使嵌入页面与嵌入式应用程序之间能够进行丰富的交互。它使用对象能力安全模型来实现各种灵活的安全策略。
    http://code.google.com/p/google-caja/
  • 09-17 15:35
    查看更多