2014-10-02 14 views
2

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

但是有一个问题!我们在 浏览器中呈现的评论如下所示:“<p>This is <em>another</em> comment</p>”。我们希望那些标签 实际上呈现为HTML。

这是React保护您免受XSS攻击。有一个办法让周围 但框架警告您不要使用它:

...

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

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

请记住:通过使用此功能,您将依靠摊牌来保证安全。

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

回答

7

大多数减价处理器(我相信也是摊牌)允许编写者使用内联HTML。例如用户可以输入:

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

因此,你应该有标签的白名单,并从降价转换为HTML后去除所有其他的标签。然后才使用恰当的名称dangerouslySetInnerHTML

请注意,这也是Stackoverflow所做的。上述降价呈现如下(没有你让你的脸泛起警报):

这是降价从过去的鬼。或者 甚至糟糕

警报( “垃圾邮件”);
1

有三个原因,最好避免HTML:

  1. 安全隐患(XSS等)
  2. 性能
  3. 事件侦听器

的安全风险主要缓解通过降价,但你仍然必须决定你认为有效的,并确保它不被允许(例如,你可能不允许图像)。

只有当标记中的内容发生变化时,性能问题才有用。例如,如果你用这个生成html:"Time: <b>" + new Date() + "</b>"。React通常会决定只更新<b/>元素的textContent,但取而代之,浏览器必须重新解析html。在更大的html块中,这是更大的问题。

如果您确实想知道某人何时点击了结果中的链接,您已经失去了简单操作的能力。您需要将onClick侦听器添加到最近的响应节点,并找出哪个元素被点击,然后从那里委派动作。

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

相关问题