为什么React.js的API警告不要插入原始HTML?

时间:2014-10-02 10:24:44

标签: security xss markdown reactjs

来自tutorial

  

但是有问题!我们呈现的评论在这里看起来像这样   浏览器:&#34; <p>This is <em>another</em> comment</p>&#34;。我们想要这些标签   实际呈现为HTML。

     

该React保护您免受XSS攻击。有办法获得   围绕它,但框架警告你不要使用它:

     

...

     

<span dangerouslySetInnerHTML={{__html: rawMarkup}} />

     

这是一个特殊的API,故意难以插入原始HTML,但对于Showdown,我们将利用这个后门。

     

请记住:通过使用此功能,您依靠Showdown是安全的。

因此存在用于插入原始HTML的API,但方法名称和文档都对其发出警告。使用它是否安全?例如,我有一个聊天应用程序,它接受Markdown注释并将它们转换为HTML字符串。 Mark片段转换器在服务器上生成HTML片段。我相信转换器,但我不确定用户是否有任何方法可以谨慎地制作Markdown以利用XSS。还有什么我应该做的,以确保这是安全的吗?

2 个答案:

答案 0 :(得分:7)

大多数Markdown处理器(我也相信Showdown)允许编写者使用内联HTML。例如,用户可以输入:

This is _markdown_ with a <marquee>ghost from the past</marquee>. Or even **worse**:
<script>
  alert("spam");
</script>

因此,您应该有一个标签白名单,并在从markdown转换为html后删除所有其他标签。然后才使用恰当命名的dangerouslySetInnerHTML

请注意,这也是Stackoverflow的功能。上面的Markdown呈现如下(没有你的脸上发出警报):

  

这是 markdown ,带有过去的幽灵。要么   甚至更糟

          警报( “垃圾邮件”);   

答案 1 :(得分:1)

避免使用html有三个原因:

  1. 安全风险(xss等)
  2. 性能
  3. 事件监听器
  4. 降价会大大减轻安全风险,但您仍需要确定您认为有效的内容,并确保其不被允许(例如,您可能不允许图片)。

    性能问题仅在标记中发生变化时才有意义。例如,如果您使用以下内容生成html:"Time: <b>" + new Date() + "</b>"。 React通常会决定只更新<b/>元素的textContent,而是替换所有内容,浏览器必须重新解析html。在较大的html块中,这更是一个问题。

    如果您确实想知道某人何时点击了结果中的链接,您就会失去这样做的能力。您需要将onClick侦听器添加到最近的反应节点,并确定单击了哪个元素,从那里委派操作。

    如果您想在React中使用Markdown,我建议使用纯反应渲染器,例如: vjeux/markdown-react