导读:本期聚焦于小伙伴创作的《PHP新增数据时如何安全插入富文本并防止XSS攻击》,敬请观看详情。把带有加粗、表格、图片的富文本直接写进数据库,页面回显时浏览器会原样解析标签,攻击者在内容里嵌入的脚本就能自动执行。正确的做法不是简单用addslashes,而是在入库前做语义化过滤,输出时再做一层转义。本文以HTML Purifier为例,说明如何只允许安全标签通过,把onerror、javascript伪协议等危险属性剔除。同时对比了转义与过滤的差异,指出仅用htmlspecialchars存储会破坏富文本结构,而只过滤不转义同样存在DOM型风险。掌握这两道关卡,才能真正做到新增数据既保留排版又不被注入。

在PHP后台接收表单提交的富文本内容并写入数据库时,开发者往往面临两难:如果原样保存,前端渲染就会执行其中的恶意脚本;如果全部转义,用户精心排版的标题、列表、图片又会变成纯文本。真正可行的方案是入库前做富文本净化,输出时再做上下文转义,两者配合才能兼顾体验与安全。

PHP新增数据时如何安全插入富文本并防止XSS攻击

为什么普通转义不适合富文本

很多初学者习惯在入库时用htmlspecialchars把所有的尖括号转成实体,这样确实能挡住XSS,但代价是富文本不再是富文本。比如用户用编辑器生成的<strong>重点</strong>,入库后变成&lt;strong&gt;重点&lt;/strong&gt;,前端展示时就只是一串字符,完全失去了加粗效果。

另一个常见误区是只用addslashes。这个函数仅仅在单引号、双引号、反斜杠前加斜杠,用来防止SQL注入尚可,但对HTML上下文中的XSS毫无作用。攻击者写入<img src=x onerror=alert(1)>,经过addslashes之后标签结构完好,输出到页面依旧会触发弹窗。因此富文本场景必须引入专门的净化逻辑。

使用HTML Purifier净化富文本

HTML Purifier是一个用PHP编写的HTML过滤库,它会根据一份严格的白名单来解析并重建HTML,丢掉所有不在允许范围内的标签和属性。相比正则替换,它基于HTML语义树处理,不容易出现绕过漏洞。下面演示如何通过Composer引入并在新增数据时调用。

先安装依赖:

composer require ezyang/htmlpurifier

接着在接收表单后做净化处理,再写入数据库:

<?php
require_once 'vendor/autoload.php';

use HTMLPurifier;

// 接收富文本
$rawHtml = $_POST['content'] ?? '';

// 配置允许的标签和属性
$config = HTMLPurifier_Config::createDefault();
$config->set('HTML.Allowed', 'p,br,strong,em,ul,ol,li,img[src|alt|width|height],a[href|title]');
$config->set('URI.AllowedSchemes', array('http' => true, 'https' => true, 'mailto' => true));
$config->set('Attr.AllowedFrameTargets', array('_blank' => true));

$purifier = new HTMLPurifier($config);
$cleanHtml = $purifier->purify($rawHtml);

// 此时 $cleanHtml 已剔除 onerror、javascript: 等危险内容
// 使用预处理语句入库,防止SQL注入
$pdo = new PDO('mysql:host=127.0.0.1;dbname=test', 'user', 'pass');
$stmt = $pdo->prepare('INSERT INTO articles (content) VALUES (?)');
$stmt->execute([$cleanHtml]);
?>

上面的配置只允许段落、换行、加粗、斜体、列表、图片和链接,并且图片和链接只接受http、https、mailto协议。像<img src=x onerror=alert(1)>里的onerror会被直接丢弃,<a href="javascript:alert(2)">的javascript协议也不在白名单内,从而从根源上消除了存储型XSS。

需要注意的是,净化后的内容虽然安全,但依然包含HTML标签。如果后续在某些非HTML上下文(如HTML属性值、JS变量)中输出,仍要做对应转义。例如把内容塞进JS字符串时,应使用json_encode而非直接拼接。

输出层的二次防护

即便数据库里存的是净化过的HTML,在模板中直接echo也不一定绝对安全。推荐在视图层统一用htmlspecialchars包裹纯文本字段,而富文本字段因为已经净化,可直接输出,但必须确保它不会被嵌入到别的危险上下文。

下面用一张表对比几种处理方式的差异:

处理方式能否保留排版防XSS效果适用场景
htmlspecialchars入库纯文本留言
addslashes入库仅防SQL注入
HTML Purifier净化富文本文章
净化+输出转义最强高安全后台

从表中可以看出,只有净化配合合理的输出策略,才能既让富文本正常显示,又堵住各类脚本注入通道。实际项目中建议封装一个统一的过滤函数,在所有新增和编辑接口中强制调用,避免人为遗漏。

常见绕过与注意事项

有些攻击者会利用大小写、嵌套、空字节或非法实体来绕过简陋的正则过滤,例如写<ImG oNeRrOr=alert(1)>。HTML Purifier在解析阶段会把标签名统一规范化,大小写混淆无效。此外,若业务需要允许用户上传图片,应单独校验图片二进制头,不能只信src里的扩展名,防止上传恶意SVG触发脚本。

还有一个容易被忽视的点:富文本中可能包含style属性,而CSS里也能写expression或url(javascript:...)这类老式攻击。因此白名单中最好不要开放style,或者采用更严格的CSS过滤器。保持最小权限原则,只放行业务真正用到的标签和属性,是长久安全的基石。

PHP富文本存储XSS防护修改时间:2026-08-09 11:18:37

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。