php防xss关键在于按上下文转义输出:html文本/属性用htmlspecialchars(ent_quotes|ent_html5,'utf-8'),js用json_encode(),url用urlencode(),富文本交由htmlpurifier白名单过滤。

PHP 防 XSS 的关键不在“过滤输入”,而在于“按上下文转义输出”。浏览器执行脚本,只取决于内容被插进 HTML 的哪个位置——同一段用户数据,在 `
` 里、在 `onclick=` 里、在 `<script>` 标签里,需要的处理方式完全不同。用错函数或漏掉上下文,`htmlspecialchars()` 也拦不住攻击。
<H3>HTML 文本与属性值:用 htmlspecialchars(),但参数不能省
<p>这是最常见也最容易出错的场景。比如显示用户名或搜索结果:
<ul>
<li>文本节点(如 `<p><?<a style="color:#f60; text-decoration:underline;" title= "php"href="https://m.php.cn/zt/15714.html" target="_blank">php echo $name; ?>`)必须用:<br>
<strong>htmlspecialchars($str, ENT_QUOTES | ENT_HTML5, 'UTF-8')<br>
`ENT_QUOTES` 防止单引号闭合属性,`'UTF-8'` 避免多字节截断绕过,`ENT_HTML5` 确保 HTML5 实体兼容。
<li>属性值(如 `<input value="<?php echo $val; ?>">`)同样用该函数,但前提是属性值必须用引号包裹;<br>
若写成 `value=<?php echo $val; ?>`(无引号),任何转义都失效——攻击者可直接注入 `onfocus=alert(1)`。
<H3>JavaScript 字符串:别用 htmlspecialchars(),用 json_encode()
<p>把 PHP 变量塞进内联 `<script>` 或 `onclick` 里,例如:<br>
<code><script>var msg = "<?php echo $user; ?>";</script><br>
此时 `htmlspecialchars()` 完全无效。它不处理 JS 语法边界、Unicode 行分隔符(`\u2028`)、`` 闭合或反斜杠逃逸问题。
<ul>
<li>正确做法是:<br><strong>json_encode($data, JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_QUOT)</strong>
</li>
<li>这个组合能安全生成 JS 字符串字面量,自动处理引号、尖括号、`&` 和 Unicode 分隔符,避免解析歧义。</li>
</ul>
<h3>URL 参数与链接 href:用 urlencode(),不是 htmlspecialchars()</h3>
<p>当用户输入拼进 URL 查询参数或跳转链接中,例如:<br><code><a href="search.php?q=<?php%20echo%20%24q;%20?>"></a></code></p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill5233" title="btpanel phpsite 宝塔面板PHP网站"><img
src="https://img.php.cn/upload/skill/000/000/081/179040786932301.jpg" alt="btpanel phpsite 宝塔面板PHP网站" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill5233" title="btpanel phpsite 宝塔面板PHP网站" class="overflowclass">btpanel phpsite 宝塔面板PHP网站</a>
<p class="overflowclass">宝塔面板 PHP 网站管理:站点创建、删除、启停、PHP 版本切换、域名管理、SSL证书管理、伪静态管理、数据库管理</p>
</div>
<a rel="nofollow" href="/xiazai/skill5233" title="btpanel phpsite 宝塔面板PHP网站" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<ul>
<li>必须用:<br><strong>urlencode($q)</strong><br>
不是 `htmlspecialchars(urlencode($q))`,更不是 `htmlspecialchars($q)`。</li>
<li>原因:URL 编码负责把空格、`&`、`/` 等转为 `%20`、`%26` 等,确保整个参数作为单个值被解析;<br>
`htmlspecialchars()` 是给 HTML 解析器看的,对 URL 解析器没意义,反而可能破坏编码结构。</li>
</ul>
<h3>富文本内容:不用转义,用 HTMLPurifier 白名单净化</h3>
<p>用户发评论、编辑文章时需保留 `<b>`、`<img>`、`<a>` 等合法标签,这时不能靠 `htmlspecialchars()`(会全干掉),也不能用正则删 `<script>`(极易绕过)。</script>
- 唯一可靠方案是引入 HTMLPurifier 库,配置白名单规则,只允许指定标签、属性和协议(如 `href` 只允许 `http://`、`https://`)。
- 它基于 DOM 解析,能识别注释绕过、嵌套畸形标签、伪协议(`javascript:`)、CSS 表达式等高级绕过手法。
- 注意:净化必须在输出前做,且不能复用已净化过的数据去其他上下文(比如把 purifier 处理过的 HTML 直接塞进 JS 字符串里)。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!