CSRF漏洞渗透与防御
CSRF漏洞定义
CSRF(Cross-site request forgery),即跨站请求伪造
- 用户登录信任的网站 A,并生成本地 cookie
- 用户未登出网站 A,cookie 并未失效
- 用户访问恶意网站 B,网站 B 页面发起对网站 A 的请求
- 用户访问网站 B 时携带了网站 A 的 cookie,网站 A 在不知情情况下接收并执行了恶意请求
CSRF的发现与检测
- 在敏感网站抓包
- 在其他网站重发请求
CSRF的检测工具
- Burp Suite
- CSRFTester
CSRF常用payload
CSRF攻击通过诱导用户在已登录状态下执行恶意请求。以下是常见的payload构造方法,按触发方式分类。
自动触发型(无需用户交互)
图片标签GET请求
使用<img>标签自动加载资源,触发GET请求。图片设置为0x0像素隐藏。
1 | <!-- 转账示例:将1000元转给攻击者账户 --> |
特点:
- 浏览器自动加载,无需用户操作
- 适用于GET请求的敏感操作
- 服务器响应会被忽略
Iframe内嵌
使用<iframe>内嵌恶意页面,自动执行请求。
1 | <!-- 隐藏iframe执行POST请求 --> |
特点:
- 可执行复杂请求
- 完全隐藏,用户不可见
用户交互型(需要点击)
诱导链接
伪装成正常链接,诱导用户点击执行GET请求。
1 | <!-- 伪装成在线聊天链接 --> |
特点:
- 需要用户主动点击
- 可伪装成各种诱人内容
- 支持_blank在新标签打开
按钮诱导
使用按钮或表单伪装,诱导用户点击提交。
1 | <!-- 伪装成抽奖按钮 --> |
自动表单提交(POST请求)
隐藏表单自动提交
构建隐藏表单,页面加载时自动提交POST请求。
1 | <!-- 自动提交转账表单 --> |
特点:
- 支持POST请求
- 可包含多个参数
- 自动执行,无需用户操作
XMLHttpRequest异步请求
使用JavaScript发送异步请求,适用于现代Web应用。
1 | <script> |
特点:
- 适用于AJAX应用
- 可设置自定义头部
- 异步执行,不阻塞页面
Fetch API请求
使用现代Fetch API发送请求。
1 | <script> |
高级payload技巧
组合攻击
1 | <!-- 结合多种方法 --> |
绕过Content-Type检查
1 | <!-- 尝试不同Content-Type --> |
针对JSON API
1 | <script> |
Payload构造注意事项
- 参数完整性:确保所有必需参数都包含
- CSRF Token处理:如果目标有token防护,需要想办法绕过或获取
- 请求方法:优先使用目标支持的方法(GET/POST)
- 隐藏技巧:使用CSS隐藏元素,避免用户察觉
- 诱导设计:让payload看起来像正常内容
测试Payload
在构造payload时,建议先在本地测试:
1 | <!-- 测试用payload --> |
通过httpbin.org等服务验证请求是否成功发送。
CSRF防御
CSRF防御是Web安全的重要组成部分,需要多层次的防护策略。以下是详细的防御方法和技术实现。
Referer验证
原理
HTTP请求头Referer由浏览器自动添加,表示当前请求的来源页面。通过检查Referer是否来自可信域名来防止CSRF攻击。
实施方法
1 | // PHP示例 |
优缺点
优点:
- 实现简单,无需修改前端代码
- 对用户透明,无额外交互
缺点:
- Referer可能被浏览器或代理过滤
- HTTPS页面Referer可能为空
- 容易被绕过(修改Referer头)
绕过方法及防护
- 绕过:攻击者可使用meta标签刷新页面或通过代理隐藏Referer
- 防护:结合其他防御方法,Referer作为辅助验证
Token验证(推荐)
原理
服务端生成随机Token,嵌入表单或请求中。客户端提交时必须携带正确Token,服务端验证Token有效性和唯一性。
实施方法
1. Token生成
1 | # Python Flask示例 |
2. 前端嵌入
1 | <!-- HTML表单 --> |
3. 服务端验证
1 | def validate_csrf_token(request_token): |
Token类型
- Session Token:与用户会话绑定
- Double Submit Cookie:Token同时存储在cookie和表单中
- Synchronizer Token:服务端维护Token状态
优缺点
优点:
- 安全性高,难以绕过
- 适用于所有请求类型
缺点:
- 需要修改前端代码
- 增加服务器状态管理复杂度
二次验证
验证码(CAPTCHA)
- 文本验证码:用户输入显示的字符
- 图片验证码:识别扭曲文字
- 行为验证码:滑动、点击验证
1 | // Google reCAPTCHA v3集成 |
密码验证
敏感操作要求重新输入密码。
1 | // PHP密码验证 |
生物识别
- 指纹识别
- 人脸识别
- 语音验证
优缺点
优点:
- 强验证,防止自动化攻击
- 用户感知明显
缺点:
- 影响用户体验
- 可能被绕过(OCR等)
SameSite Cookie属性
原理
Cookie的SameSite属性控制跨站请求是否携带Cookie。
配置方法
1 | // 设置SameSite |
SameSite值
- Strict:完全阻止跨站请求携带Cookie
- Lax:允许顶级导航(如链接点击)
- None:允许所有跨站请求(需HTTPS)
兼容性
- Chrome 80+ 默认Lax
- Safari 12+ 支持
- Firefox 69+ 支持
Origin头检查
原理
检查Origin或Host头是否来自可信来源。
1 | // 检查Origin头 |
与Referer区别
- Origin更可靠(不包含路径)
- HTTPS下更安全
自定义头部验证
原理
要求请求包含自定义HTTP头部,只有同源请求能设置。
1 | // 前端设置自定义头 |
1 | # 服务端验证 |
组合防御策略
多层防护
- 主要防御:Token验证
- 辅助防御:Referer检查 + SameSite Cookie
- 敏感操作:二次验证
实施指南
1 | // 前端防御组合 |
框架内置防护
- Django:
{% csrf_token %}标签 - Spring Security:自动Token管理
- Express.js:csurf中间件
1 | // Express.js CSRF防护 |
防御最佳实践
1. 风险评估
- 识别敏感操作(转账、密码修改、删除)
- 根据风险等级选择防御强度
2. 开发规范
- 所有状态改变请求必须验证
- 避免GET请求执行敏感操作
- 使用HTTPS强制传输
3. 测试验证
- 单元测试CSRF防护逻辑
- 集成测试跨站请求场景
- 定期安全审计
4. 监控告警
- 记录CSRF尝试
- 异常检测和告警
- 定期审查日志
5. 用户教育
- 避免点击可疑链接
- 及时登出账户
- 使用密码管理器
常见误区
- 只依赖Referer:容易绕过,应作为辅助
- 忽略JSON API:API请求也需要CSRF防护
- Token重用:每个请求使用唯一Token
- 忽略子域名:检查完整域名匹配
通过实施这些深度防御措施,可以有效防止CSRF攻击,保护用户账户安全。
CSRF与XSS的区别
虽然CSRF(跨站请求伪造)和XSS(跨站脚本攻击)都是常见的Web安全漏洞,且都与“跨站”相关,但它们在原理、利用方式和影响上有着本质区别。理解两者的差异有助于更好地防范和应对。
定义对比
- CSRF:攻击者诱导用户在已认证状态下执行非预期操作,利用用户的身份权限进行恶意请求
- XSS:攻击者向网页注入恶意脚本,当用户浏览页面时执行,窃取用户信息或执行其他操作
攻击原理
| 方面 | CSRF | XSS |
|---|---|---|
| 触发方式 | 诱导用户访问恶意页面,自动发送请求 | 注入恶意脚本到页面,用户浏览时执行 |
| 利用对象 | 用户的认证状态(Cookie等) | 用户的浏览器环境 |
| 执行主体 | 服务器端处理用户请求 | 客户端浏览器执行脚本 |
| 权限依赖 | 依赖受害者的登录状态 | 不需要受害者登录 |
利用方式
CSRF利用特点
- 通过构造恶意链接或表单诱导用户点击
- 利用浏览器自动发送Cookie的行为
- 攻击者无法直接获取响应内容
- 常用于状态改变操作(如转账、修改密码)
XSS利用特点
- 通过输入字段注入脚本代码
- 脚本在受害者浏览器中执行
- 可以窃取Cookie、Session等敏感信息
- 可以修改页面内容或重定向用户
影响范围
CSRF影响
- 用户数据:修改、删除用户数据
- 账户安全:转账、修改密码、删除账户
- 系统操作:执行管理员操作(如批量删除)
- 间接影响:通过用户权限间接影响系统
XSS影响
- 信息泄露:窃取用户凭证、个人数据
- 会话劫持:控制用户会话
- 钓鱼攻击:伪造页面诱导输入敏感信息
- 蠕虫传播:在社交平台自动传播
防御措施对比
CSRF防御重点
- Token验证(推荐)
- Referer检查
- SameSite Cookie
- 二次验证(敏感操作)
XSS防御重点
- 输入过滤和转义
- Content Security Policy (CSP)
- HttpOnly Cookie
- 输出编码
实际案例对比
CSRF案例
- 银行转账:诱导用户点击链接,转走账户资金
- 社交平台:自动发布恶意内容或关注攻击者
- 电商平台:修改收货地址或取消订单
XSS案例
- 论坛系统:注入脚本窃取其他用户Cookie
- 搜索框:反射型XSS弹出恶意窗口
- 评论系统:存储型XSS影响所有浏览者
检测与测试
CSRF检测
- 检查状态改变请求是否有CSRF防护
- 构造跨站请求测试是否执行
- 分析Cookie依赖的操作
XSS检测
- 测试输入字段是否过滤特殊字符
- 检查输出是否正确转义
- 验证CSP策略是否生效
总结
| 特性 | CSRF | XSS |
|---|---|---|
| 本质 | 请求伪造 | 脚本注入 |
| 受害者 | 已登录用户 | 所有浏览者 |
| 攻击目标 | 服务器操作 | 客户端数据 |
| 防御重点 | 请求验证 | 输入输出控制 |
| 影响程度 | 中等(操作执行) | 高(信息泄露) |
DVWA靶场实战
理解CSRF与XSS的区别有助于开发人员选择合适的防御策略。在实际应用中,往往需要同时防范两种攻击,以确保Web应用的安全性。
用1337/charley登录DVWA靶场,找到CSRF关卡,我用的靶场等级为low


页面功能为修改密码,我们尝试将密码修改为123456,并抓包,提交方式为GET,只要拿到修改的代码参数就能进行伪造

我做了两个比较刺激的html页面

当你在浏览器中访问index.html,没忍住诱惑,点击了网页中的链接
1 | <!--index.html--> |

浏览器会跳到out.html中,在out.html内置好了请求参数,将1337用户的密码改为654321
1 | <!--out.html--> |

这个时候你再回去,发现1337账号的密码已经被改了,登录不上去了







