【问题标题】:Security comparison of eval and innerHTML for clientside javascript?客户端javascript的eval和innerHTML的安全比较?
【发布时间】:2013-05-31 14:58:35
【问题描述】:

我一直在用 innerHTML 进行一些试验,试图找出我需要在我正在开发的 web 应用程序上加强安全性的地方,我在the mozilla docs 上遇到了一种我没有的有趣注入方法想了想。

var name = "<img src=x onerror=alert(1)>";
element.innerHTML = name; // Instantly runs code.

这让我想知道 a.) 我是否应该使用 innerHTML,以及 b.) 如果这不是问题,为什么我一直避免使用其他代码插入方法,尤其是 eval。

假设我在浏览器上运行 javascript 客户端,并且我正在采取必要的预防措施以避免在易于访问的函数中暴露任何敏感信息,并且我已经达到了一个任意指定的点,我已经决定 innerHTML 是不是安全风险,而且我已经优化了我的代码,以至于我不必担心性能受到非常小的影响......

使用 eval 是否会产生其他问题?除了纯代码注入还有其他安全问题吗?

或者,innerHTML 是我应该表现出同样关心的东西吗?是否同样危险?

【问题讨论】:

  • 风险始终在于让一个用户生成的内容在另一个用户会话的上下文中运行。如果我编写一个脚本,在我自己的浏览器中运行它没什么大不了的,但如果该脚本被存储并在其他人的浏览器中运行,那大不了的。
  • 你问是否应该使用innerHTML eval,因为它们不相似
  • @ExplosionPills - 更多的是“我应该使用其中一个吗?”我想知道有什么区别。它们是纯粹类似的安全风险,还是其中一种风险比另一种风险更大?为什么?
  • @user2267361:eval() 的基线比innerHTML 更危险。但是,如果您允许在innerHTML 中插入script 标记或事件处理程序,则基本上您已授予他们对eval 的访问权限。
  • @apsillers:确实。我从来没有说过别的。脚本标记或事件处理程序.

标签: javascript html


【解决方案1】:

tl;博士;

是的,你的假设是正确的。

如果您要添加不受信任的代码,设置 innerHTML 很容易受到 XSS 攻击。

(不过,如果您要添加 您的 代码,那问题就不大了)

如果您想添加用户添加的文本,请考虑使用textContent,它会转义它。

问题是什么

innerHTML 设置 DOM 节点的 HTML 内容。当您将 DOM 节点的内容设置为任意字符串时,如果您接受用户输入,则容易受到 XSS 攻击。

例如,如果您根据来自GET 参数的用户输入设置节点的innerHTML。 “用户 A”可以向“用户 B”发送一个带有 HTML 的页面版本,上面写着“窃取用户的数据并通过 AJAX 将其发送给我”。

在此处查看this question 了解更多信息。

我可以做些什么来减轻它?

如果要设置节点的 HTML,您可能需要考虑的是:

  • 使用像Mustache 这样具有转义功能的模板引擎。 (默认情况下会转义 HTML)
  • 使用textContent手动设置节点文本
  • 不接受用户对文本字段的任意输入,自行清理数据。

请参阅this question,了解更通用的防止 XSS 的方法。

代码注入一个问题。你不想成为接收端。

房间里的大象

这不是innerHTMLeval 的唯一问题。当您更改 DOM 节点的 innerHTML 时,您正在销毁其内容节点并创建新节点。当您调用 eval 时,您正在调用编译器。

虽然这里的主要问题显然是不受信任的代码,并且您说性能不是问题,但我仍然觉得我必须提到这两者对于它们的替代方案非常慢。

【讨论】:

  • 这很完美,在此之前我根本没有研究过数据卫生。
  • @w5m 哇,我想我真的累了 -_-' ,我的拼写通常好多了。非常感谢您的编辑。 OP,我很高兴你发现这个答案很有用,如果你对 XSS 有任何疑问,请随时在 SO 的 JS 聊天中顺便过来。
【解决方案2】:

快速的回答是:你没有想到任何新东西。如果有的话,你想要一个更好的吗?

<scr\0ipt>alert("XSSed");</scr\0ipt>

底线是触发 XSS 的方法比您想象的要多。以下都是有效的:

  • onerroronloadonclickonhoveronblur 等...都是有效的
  • 使用字符编码绕过过滤器(上面突出显示的空字节)

eval 属于另一个类别,但是 - 它是一个副产品,大多数情况下是为了混淆。如果你落入eval 而不是innerHTML,那么你就属于极少数。

所有这一切的关键是使用解析器清理您的数据,该解析器与渗透测试人员的发现保持同步。周围有几个。他们绝对需要至少过滤 OWASP 列表中的所有内容 - 这些非常常见。

【讨论】:

  • +1 表示空字符...哦,我的上帝!!!!!!!我有一些过滤器可以调整我的代码!!!!
  • @rupps:你用哪种语言编码?如果您使用 PHP 进行过滤,htmlpurifier.org 可能值得作为自定义过滤器之前的第一步。处理 OWASP 列表中的大部分案例。
  • 我有大量自己开发的客户端库,但感谢您的提示......随着 XSS 越来越流行,依靠社区维护的库来摆脱辉煌是有意义的每隔一天就会发现新的讨厌鬼……
  • OWASP 的空字符非常好用!,我认为应该从这个事实中得到一个应该列入白名单而不是列入黑名单的事实。
【解决方案3】:

innerHTML 本身并不是不安全的。 (eval 也不是,如果仅用于您的 代码。出于几个其他 原因,这实际上是一个坏主意。)显示访问者提交的内容时会出现不安全性.这种风险适用于您嵌入用户内容的任何机制:evalinnerHTML 等在客户端,printecho 等在服务器端。

您从访问者那里放置在页面上的任何内容都必须经过清理。无论您是在初始页面正在构建还是在客户端异步添加时执行此操作都无关紧要。

所以...是的,您在使用innerHTML 时需要格外小心如果您正在使用它来显示用户提交的内容。

【讨论】:

    猜你喜欢
    • 2022-12-17
    • 1970-01-01
    • 2020-01-24
    • 2016-12-27
    • 1970-01-01
    • 2017-11-16
    • 2012-07-24
    • 1970-01-01
    • 2010-12-09
    相关资源
    最近更新 更多