代码之家  ›  专栏  ›  技术社区  ›  Phil H

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

  •  6
  • Phil H  · 技术社区  · 17 年前

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

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

    所以,我能禁止吗 eval() 从提交的文件中选择并完成?或者有其他方法来评估代码,或者在javascript中引起大规模恐慌?

    还有其他事情要禁止,但我的主要担心是,除非我能阻止字符串被执行,否则我为特定方法设置的任何其他过滤器都可以避免。可行,还是我必须求助于要求作者提供Web服务接口?

    6 回复  |  直到 11 年前
        1
  •  8
  •   bobince    17 年前

    或者有其他评估代码的方法吗?

    您无法筛选出对的呼叫 eval() 在脚本解析级别,因为javascript是一种图灵完整语言,在这种语言中可以混淆调用。见斯文托的解决办法。你可以隐藏 window.eval 通过用一个空值覆盖它,但实际上还有其他方法来评估代码,包括(在我的头上):

    • 新函数(“代码”)()
    • document.write('%3cscript>代码%3c/script>')
    • document.createElement('script').appendChild(document.createTextNode('code'))
    • window.settimeout(“代码”,0);
    • window.open(…).eval('code')
    • location.href='javascript:code'
    • 在IE中,style/node.setexpression(“someproperty”,“code”)。
    • 在某些浏览器中,node.onsomeevent='code';
    • 在旧的浏览器中,object.prototype.eval(“code”)。

    或者在javascript中引起大规模恐慌?

    well createElement('iframe').src='http_://evil.iframeExploiz.ru/aff=2345'是您可以预料到的最糟糕的攻击之一…但实际上,当一个脚本拥有控制权时,它可以做用户在您的站点上可以做的任何事情。它可以使他们成为一个“我是一个大的老恋童癖者”!_在您的论坛上一千次,然后删除自己的帐户。例如。

    我是否必须求助于要求作者提供Web服务界面?

    是的,或者:

    • 不做任何事情,让想要这个功能的用户下载greasemonkey
    • 亲自审核每个脚本提交
    • 使用您自己的(可能是类似于javascript的)迷你语言,您可以实际控制它。

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

        2
  •  12
  •   Community Mohan Dere    9 年前

    自从 HTML5 现在可以使用 sandbox 对于不受信任的javascript代码。

    这个 OWASP HTML5 Security Cheat Sheet 评论 Sandboxed frames :

    • 对不受信任的内容使用iframe的sandbox属性。
    • iframe的sandbox属性启用对 iframe . 设置沙盒属性时,以下限制处于活动状态:

      1. 所有标记都被视为来自唯一来源。

      2. 所有窗体和脚本都被禁用。

      3. 所有链接都被阻止以其他浏览上下文为目标。
      4. 自动触发的所有功能都将被阻止。
      5. 所有插件都被禁用。

        可以对 伊夫拉姆 使用 sandbox 属性。

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

    • 除了此属性之外,为了防止点击劫持攻击和未经请求的帧,建议使用头部 X-Frame-Options 它支持 deny same-origin 价值观。其他解决方案,如框架破坏 if(window!== window.top) { window.top.location = location; } 不推荐。

    您可以允许脚本运行,同时保留其他限制。但是,为了防止 XSS 攻击者重定向用户直接加载页面的攻击(即不通过您的iframe)。

    这将限制脚本使用 eval 攻击您的主域,但这也可能会阻止脚本实际上足够强大以满足您的需要。任何与主域的交互都必须通过 Window.postMessage . 如果这太限制了,那么 @bobince's answer 对于解决方法仍然有最好的建议。

    请看 my other answer 有关如何安全实现沙盒的详细信息。

        3
  •  5
  •   Anthony    17 年前

    允许任意的javascript执行是不安全的。实际上,为防止恶意代码而提供的任何过滤都会删除访问类似函数或数据的合法代码。我不认为你想这样做是可行的。

        4
  •  1
  •   jpalecek    17 年前

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

    如果你的站点不需要这个用户提供的JS在其他用户的计算机上运行,我只需要发出一个巨大的警告,添加一些人工控制(这样可以标记流氓代码),或者服务器上的一些防病毒软件(对此不太了解)。

        5
  •  0
  •   Svante Svenson    17 年前

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

        6
  •  0
  •   Timmerz    11 年前

    您需要在沙盒环境中执行不受信任的代码。这意味着使用 sandbox 属性(见) this article 另外,在该框架内创建一个Web工作者(这样代码在单独的线程中运行,并且在用户提交了一些奇怪的东西时不会挂起UI)。

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