PHP防XSS关键在正确使用htmlspecialchars(),必须传入ENT_QUOTES和'UTF-8'三参数;HTML属性需匹配引号转义;URL属性须先urlencode();JS上下文应改用json_encode();富文本须用HTMLPurifier等净化库。

PHP本身没有“防XSS的标签”,真正起作用的是输出时调用的转义函数,尤其是htmlspecialchars()。关键不是加什么标签,而是在哪加、怎么加、加对不对——漏掉单引号、不指定编码、用错上下文,都可能让防护形同虚设。
必须用 htmlspecialchars(),且带全三个参数
这是最常用也最容易出错的一环。只写htmlspecialchars($input)是危险的,默认不转义单引号,在属性值中直接失效。
- 第一个参数:要处理的用户输入字符串
- 第二个参数:必须是
ENT_QUOTES,确保双引号和单引号都被转义 - 第三个参数:必须显式写
'UTF-8',避免因默认编码不一致被绕过
✅ 正确写法:echo htmlspecialchars($user_input, ENT_QUOTES, 'UTF-8');
❌ 错误写法:echo htmlspecialchars($user_input);(缺参数,单引号不转)
别在HTML属性里裸插变量
把用户数据塞进title="{{ $name }}"或data-id="{{ $id }}"这类属性时,光转义和<code>>完全没用。
- 如果属性用双引号包裹(
title="xxx"),必须确保"被转成" - 如果用单引号包裹(
title='xxx'),必须确保'被转成'或' -
ENT_QUOTES就是干这个的——它同时覆盖两种引号场景
⚠️ 特别注意:href或src这类URL属性,不能只靠htmlspecialchars()。得先用urlencode()编码值本身,再拼进带引号的属性里。
立即学习“PHP免费学习笔记(深入)”;
绝对不要在JS上下文中混用HTML转义
像<script>alert("= $user_input ?>")</script>这种写法,看似用了引号,实则极危险。
-
htmlspecialchars()防的是HTML解析,不是JS执行 - 用户输入
"; alert(1); //会直接打破字符串并执行代码 - 正确做法:把用户数据先用
json_encode()编码,再放入JS字符串中
✅ 安全示例:<script>const name = = json_encode($user_input, JSON_UNESCAPED_UNICODE) ?>;</script>
富文本内容不能靠转义,得用净化库
如果业务允许用户发带格式的内容(比如评论含链接、加粗),htmlspecialchars()会把所有标签都变成纯文本,失去功能。
- 此时必须用专业净化库,如
HTMLPurifier或DOMPurify(后端PHP可用htmlawed等) - 配置白名单:只保留
p、a、strong等安全标签 - 严格过滤属性:禁用
onerror、onclick、javascript:等一切可执行逻辑
⚠️ 切勿自己写正则删<script>——<scr<script>ipt>或<img src=x onerror=alert(1)>都能轻松绕过。



















