如何在存储用户内容的同时避免XSS漏洞

How to store user content while avoiding XSS vulnerabilities

我知道有人问过类似的问题,但我正在努力弄清楚该怎么做。

我正在构建一个 CMS,现在相当原始,但它是一种学习练习;在生产站点中,我肯定会使用现有的解决方案。

我想接受用户输入,可以在所见即所得编辑器中设置样式。我也希望他们能够内联插入图像。

我知道我可以将 HTML 存储在数据库中,但我怎样才能安全地重新呈现它。我知道存储 HTML 没有问题,但我的理解是,如果我只是简单地将用户生成的代码转储到布局模板上,XSS 就会成为一个问题。

所以简单地说,问题是如何在 cms 中存储和安全地重新呈现用户内容?我正在使用 Laravel 和 PHP。如果需要的话,我对 javascript 也略知一二。

避免跨站点脚本的一个好又便宜的方法是让您的 php 程序在将用户输入的所有内容存储到数据库之前对其进行实体化。也就是说,您想从用户那里获取此条目

Hi there sucker! I just hacked your site.
<script>alert('You have been pwned!')</script>

并在将其放入数据库之前将其转换为此格式。

Hi there sucker! I just hacked your site.
&lt;script&gt;alert('You have been pwned!')&lt;/script&gt;

当您将 &lt; 传递给浏览器时,它会将其呈现为 <,但不会对其执行任何其他操作。

如果需要,htmlentities() function can do this for you. And, php's htmlspecialchars_decode() 可以将其反转。但是你不应该反转操作,除非你绝对必须这样做,例如将文档加载到嵌入式编辑器中进行更改。

您还可以选择在从数据库中检索用户提供的文本之后和显示之前实体化用户提供的文本。如果您到了需要多人处理您的代码的地步,为了安全起见,您可能希望两者都做。

您还可以在 <pre>content</pre> 标记内呈现用户提供的输入,这会告诉浏览器只呈现文本而不对其进行任何其他操作。

(在此页面上右键单击“检查”以查看 Stack Overflow 如何处理我的恶意示例。)

对于您希望允许某些标签但不允许其他标签的 CMS,您需要类似 HTML Purifier 的东西。这会将 HTML 和 运行 与白名单进行比较,并重新生成 HTML 以安全地显示给用户。