thinkphp 8.0需手动分上下文防护xss与csrf:xss须按html内容、属性、js内联、富文本四类分别处理;csrf需显式启用并校验token;csp需配合nonce头与模板使用;禁用全局过滤、diy净化等高危操作。

ThinkPHP 8.0 没有“开个开关就安全”的配置,XSS 和 CSRF 防护必须分上下文、手动落实。框架已移除 default_filter 自动兜底,也不再默认转义模板变量,依赖旧习惯会直接导致漏洞。
XSS 防护:按输出位置分别处理
不能只靠一个 htmlspecialchars 或全局过滤。不同输出场景必须用对应方式:
-
HTML 文本内容(如段落、标题):模板中用
{:htmlspecialchars($var, ENT_QUOTES | ENT_HTML5, 'UTF-8')};简写{$var|html}仅限 TP8.0.1+,但不转义单引号,慎用 - HTML 属性值(如 title="{$title}"):必须用双引号或单引号包裹属性,并确保内容已按 HTML 上下文转义;空格、等号、未闭合引号都可能截断属性并注入事件
-
JS 字符串内联(如
<script>var data = "{$data}";</script>):绝对不用 htmlspecialchars,改用json_encode($data, JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_QUOT) -
富文本(TinyMCE、wangEditor 等提交的内容):必须用 HTMLPurifier 白名单净化;安装
composer require ezyang/htmlpurifier,配置显式允许标签(如p,b,i,a[href|title],img[src|alt]),并开启Core.RemoveScriptContents和URI.AllowedSchemes
CSRF 防护:必须显式启用并校验
TP8 默认不开启 CSRF 保护,token() 只是生成字段,不校验等于没防:
- 在
config/app.php中设'form_token' => true,同时配好'token_salt'和'token_ttl'(建议 300–3600 秒) - 路由层最可靠:POST/PUT/DELETE 路由加
->option(['token' => true]);资源路由需单独为store、update设置 - 表单页面必须调用
{:token()}(生成隐藏域),AJAX 提交时需把返回值作为_token字段传入请求体 - 避免多标签页失效:默认 token 支持同 action 多次复用;如需每次刷新强制更新,用
{:token('edit', true)}
CSP 响应头:配合 nonce 防内联脚本
仅靠 PHP 过滤不够,CSP 是浏览器端最后一道防线:
- 写一个中间件(如
CspMiddleware),在handle()中生成随机 nonce(base64_encode(random_bytes(16))),存入 View 共享变量(如$this->view->assign('nonce', $nonce)) - 用
$response->header('Content-Security-Policy', "script-src 'self' 'nonce-{$nonce}' ...")注入响应头 - 模板中内联脚本写成
<script nonce="{$nonce}">...</script>;禁用'unsafe-inline',不依赖哈希(维护成本高) - 开发期先用
Content-Security-Policy-Report-Only+report-uri收集日志;report 路由要单独定义为免登录、免 CSRF 的 POST 接口
避坑提醒:这些操作反而引入风险
常见“看似防护实则无效甚至有害”的做法:
- 在中间件里遍历
$_POST全局 htmlspecialchars —— 数据污染,JSON 输出、数据库写入、URL 拼接都会出错 - 控制器里每次 new HTMLPurifier() —— 重复加载 DTD,性能差;应注册为容器单例或封装 clean() 服务
- 用
strip_tags()或正则 DIY 富文本过滤 ——<img src="x" onerror="alert(1)">、<svg onload="..."></svg>全部绕过 - GET 请求做删除/修改操作 —— FormTokenCheck 不校验 GET,这类接口天然可被 CSRF 利用
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











