PHP 如何防止 XSS

在网页开发中,你可能遇到过这样的情况:用户在评论区输入一段文字,结果其他用户看到的内容里突然出现了奇怪的弹窗,或者原本的排版被打乱了——这很可能是XSS攻击在作祟。简单来说,XSS就是黑客通过在网页里插入恶意代码,让其他用户浏览时中招。对用PHP做后端的开发者来说,做好这一步防护,就能帮网站避开不少麻烦。

先搞懂:XSS攻击到底是什么?

举个生活化的例子:你开了一家小店,允许顾客在留言板上写评价。有个顾客故意在留言里写了<script>偷取你的顾客手机号并发给黑客</script>,而你直接把这段内容原样展示给其他顾客,就等于把小偷的“作案工具”直接贴在店里的公告栏上。

PHP 如何防止 XSS

这种攻击的核心就是“未过滤输入的内容”。PHP作为后端工具,要做的就是在把用户输入的内容展示给其他人之前,把危险的代码“处理掉”,让它变成普通文字,没法被浏览器当成代码执行。

最基础的防护:把特殊字符转成“安全模样”

用户输入的内容里,最危险的就是<</code>、>、"、'这些HTML特殊符号,它们是浏览器识别代码的标志。PHP里有个专门的函数htmlspecialchars(),能把这些符号转成浏览器不会当成代码的字符,比如把<</code>转成&lt;,>转成&gt;。

举个例子:如果用户输入的是<script>alert('偷东西')</script>,用htmlspecialchars()处理后,会变成&lt;script&gt;alert('偷东西')&lt;/script&gt;。这样其他用户看到的就是一串普通文字,不会弹出弹窗,也没法执行恶意代码。

要注意,这个函数要在输出内容到页面的时候用,而不是在存进数据库之前。因为存进数据库的话,可能会有其他场景需要用到原始内容,比如后台查看评论,这时候如果转义了反而会显示乱码。

别踩坑:纯文本输出更安全的场景

如果你的功能是展示用户输入的纯内容,比如评论区、个人简介,还有个更简单的方法:用htmlspecialchars()的变种htmlentities()?不对,其实更适合纯文本输出的是PHP的strip_tags(),它能直接把所有HTML和PHP标签都删掉。

比如用户输入了

我很喜欢这家店!

,用strip_tags()处理后,就只剩下“我很喜欢这家店!”,连段落标签都没了。不过这个方法适合不需要保留格式的场景,如果需要保留加粗、链接这些格式,还是用htmlspecialchars()更灵活。

另外,不管用哪个函数,都要记得指定字符编码,比如htmlspecialchars($content, ENT_QUOTES, 'UTF-8'),这是因为ENT_QUOTES会同时转义单引号和双引号,避免黑客用引号绕开防护;UTF-8则是现在最通用的网页编码,能防止乱码。

进阶防护:别忽略特殊场景的风险

如果你的网站有需要处理用户上传的内容,比如文章编辑器,可能会允许用户插入部分HTML标签(比如<b>、<i>、),这时候不能直接用strip_tags()全删,也不能只用htmlspecialchars()全转。这时候可以用strip_tags()的第二个参数,指定允许保留的标签。

比如strip_tags($content, '<b><i>'),就只会保留加粗、斜体和链接标签,其他所有标签都会被删掉。还要记得对标签的href属性做进一步检查,防止黑客插入disabled:开头的恶意链接——比如链接,这时候可以用preg_match()检查href是否是合法的http://或https://开头的链接,过滤掉危险的disabled:。

最后还要提醒一句:防护XSS不止是后端的事,前端也可以做辅助,比如给输入框加限制,禁止输入特殊字符,但后端的过滤才是最后一道防线,不能完全依赖前端。只有前后端配合,才能真正把XSS攻击挡在门外。

上一篇 JavaScript instanceof 怎么用