在 Web 开发中,跨站脚本攻击(XSS)是一种常见且危险的安全威胁。攻击者通过注入恶意脚本代码,使得浏览器执行非预期的行为,窃取用户信息、劫持会话,甚至控制用户的浏览器。为了防止 XSS,开发者通常会对用户输入进行严格的过滤和编码处理。在 PHP 中,htmlspecialchars() 是最常用的防护手段之一。然而,若用户提交的内容中包含无效或非法的字符序列,仅使用 htmlspecialchars() 可能无法完全防止漏洞,这时候就需要结合 mb_scrub() 来进行更稳健的处理。
mb_scrub() 是 PHP 8.2 引入的函数,作用是“清洗”包含非法字符的多字节字符串,使其成为一个合法的字符串。多字节字符在传输或处理过程中如果被截断,可能形成无效的字符序列。这种非法序列若直接传入 htmlspecialchars(),在某些条件下可能会绕过预期的转义机制。
例如,一个非法的 UTF-8 字节序列可能在浏览器中被错误解析,从而导致脚本注入。
<span><span><span class="hljs-comment">// 示例:包含非法字节的输入</span></span><span>
</span><span><span class="hljs-variable">$input</span></span><span> = </span><span><span class="hljs-string">"\xC0<script>alert('XSS');</script>"</span></span><span>;
</span><span><span class="hljs-comment">// 直接使用 htmlspecialchars(不安全)</span></span><span>
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-title function_ invoke__">htmlspecialchars</span></span><span>(</span><span><span class="hljs-variable">$input</span></span><span>, ENT_QUOTES, </span><span><span class="hljs-string">'UTF-8'</span></span><span>);
</span></span>
上面的例子中,如果 $input 包含非法的 UTF-8 字节,浏览器可能忽略这些字节并执行后续的 <script> 标签。
为了解决这个问题,我们可以先使用 mb_scrub() 清洗字符串,再传递给 htmlspecialchars() 进行 HTML 实体转义。
<span><span><span class="hljs-comment">// 安全做法:先清洗,再转义</span></span><span>
</span><span><span class="hljs-variable">$clean</span></span><span> = </span><span><span class="hljs-title function_ invoke__">mb_scrub</span></span><span>(</span><span><span class="hljs-variable">$input</span></span><span>, </span><span><span class="hljs-string">'UTF-8'</span></span><span>);
</span><span><span class="hljs-variable">$safe</span></span><span> = </span><span><span class="hljs-title function_ invoke__">htmlspecialchars</span></span><span>(</span><span><span class="hljs-variable">$clean</span></span><span>, ENT_QUOTES, </span><span><span class="hljs-string">'UTF-8'</span></span><span>);
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-variable">$safe</span></span><span>;
</span></span>
这种组合的优势在于:
mb_scrub() 保证字符序列的合法性:无效字符被修复或剔除,防止浏览器在处理非法编码时出错。
htmlspecialchars() 提供标签转义:将 <, >, ", ' 等字符转换为 HTML 实体,防止 HTML 注入。
总是指定字符集为 UTF-8,确保跨平台一致性。
对所有用户输入进行清洗和转义,尤其是输出到 HTML 时。
配合 Content-Security-Policy (CSP) 使用,进一步降低 XSS 风险。
升级到 PHP 8.2 或更高版本,以使用 mb_scrub() 函数。
虽然 htmlspecialchars() 是防止 XSS 的基础工具,但它并非万能。如果用户输入中包含非法字符编码,有可能引发安全漏洞。通过在其之前加入 mb_scrub(),可以有效清除非法字符,增强防护强度。对于追求更高安全标准的 PHP 开发者来说,这种组合值得推广使用。