这篇文章是我在学习的时候遇到的一写简单问题,只对0基础的可能有用,要了解有防护的情况下的绕过的话,这篇文章没有涉及,防止浪费大家时间,嘻嘻~~~

一、什么是CSRF?
1.1 定义
CSRF(Cross-Site Request Forgery,跨站请求伪造),是一种利用用户已登录的身份,在用户不知情的情况下执行非本意操作的攻击方式。
1.2 一句话理解
黑客利用你浏览器里存着的"登录凭证"(Cookie),偷偷让你执行了你不想执行的操作。
二、CSRF的三个必要条件
CSRF攻击要成功,必须同时满足以下三个条件:
① 用户登录目标网站                      Cookie/Session仍在有效期内
② 目标网站只靠Cookie识别身份        没有Token、没有验证码、没有二次确认
③ 黑客能构造出攻击请求               能预测URL/参数,或能诱导用户触发
缺一不可。任何一个条件不满足,CSRF攻击就会失败。
三、CSRF的核心原理
3.1 浏览器的"自动带牌"机制
比如:当你登录一个银行账户 bank.com 后:
服务器:给你发送一个Set-Cookie: session_id=abc123
浏览器:好的,我存起来!
浏览器:以后每次访问 bank.com,我都自动带上这个Cookie(浏览器的自带规则)
关键点:
只要目标是 bank.com,浏览器就自动带上Cookie
这是HTTP协议规范,浏览器必须这么干

3.2 同源策略的"盲区"
同源策略(SOP)是浏览器的安全基石,但它存在一个"盲区":
同源策略允许:evil.com 向 bank.com 发请求    
同源策略禁止:evil.com 读取 bank.com 的返回数据
结论:
攻击者能发出转账请求 ✅
攻击者看不到转账结果 ❌
但钱已经转走了,看不看结果已经不重要了
CSRF就是"只发不看"的攻击。
3.3 攻击流程图
用户的浏览器
├── 存着 bank.com(银行的网址) 的 Cookie(身份令牌)
└── 用户打开 evil.com(黑客的网页)后端里藏着一行代码:<img src="https://bank.com/transfer?to=hacker\&money=10000">
                ↓
           浏览器向 bank.com 发起请求
                ↓
           自动带上 Cookie(因为目标是 bank.com)
                ↓
           bank.com 后端验证通过 → 转账成功!
                ↓
           返回结果(但同源策略不让 evil.com 读取)
                ↓
           但钱已经没了!结果看不看得到已经不重要了
四、CSRF的攻击分类
4.1 GET型CSRF(最简单)
原理:将恶意请求放在 <img>、<link>、<script> 等标签的 src 属性中,浏览器会自动加载并发送GET请求。

攻击代码:
html
<img src="http://bank.com/transfer?to=hacker&amount=10000" style="display:none">
触发方式:用户打开页面 → 浏览器自动加载"图片" → 转账请求发出
特点:不需要任何JavaScript,纯HTML即可完成攻击

4.2 POST型CSRF(同样危险)
原理:构造隐藏表单,用JavaScript自动提交

攻击代码:
html
<form id="hack" action="http://bank.com/transfer" method="POST">
    <input type="hidden" name="toAccount" value="hacker">
    <input type="hidden" name="amount" value="10000">
</form>
<script>
    document.getElementById('hack').submit();  // 自动提交!
</script>
特点:需要少量JavaScript(仅submit()调用),但同样无需用户交互
五、为什么需要"跨站"?
直接攻击为什么不行?
如果黑客直接发链接:
http://bank.com/transfer?to=hacker&amount=10000
用户点击后会看到银行页面显示"转账成功",当场发现,攻击失败。
为什么需要跨站?
         │
         ├── 目的1:隐藏攻击
         │    ├── 不跨站:用户看到"转账成功" → 当场发现
         │    └── 跨站:用户看到"404/中奖" → 完全不知情
         │
         ├── 目的2:支持POST
         │    ├── 不跨站:只能发GET(URL直接访问)
         │    └── 跨站:可以发POST(隐藏表单+JS提交)
         │
         └── 目的3:利用同源策略盲区
              ├── evil.com 可以发请求到 bank.com 
              └── evil.com 不能读响应 → 但攻击不看结果 
六、完整攻击实战(DVWA案例)
6.1 漏洞代码分析
DVWA(Damn Vulnerable Web Application)Low安全级别的密码修改功能:

php
<?php
if( isset( $_GET[ 'Change' ] ) ) {
    $pass_new  = $_GET[ 'password_new' ];
    $pass_conf = $_GET[ 'password_conf' ];
    
    if( $pass_new == $pass_conf ) {
        $pass_new = mysqli_real_escape_string($conn, $pass_new);
        $pass_new = md5($pass_new);
        
        $insert = "UPDATE users SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "'";
        mysqli_query($conn, $insert);
        
        echo "<pre>Password Changed.</pre>";
    }
}
?>
6.2攻击代码
html
<!-- 放在 www 目录下的 1.html -->
<img src="http://127.0.0.1/DVWA/vulnerabilities/csrf/?password_new=123456&password_conf=123456&Change=Change#" 
     border="0" style="display:none;"/>

<h1>404</h1>
<h2>file not found.</h2>
6.3 攻击条件
用户已登录DVWA    Cookie有效
安全级别为Low    没有Token保护
用HTTP协议访问    http://127.0.0.1/1.html
⚠️ 重要:必须通过 http://127.0.0.1/1.html 访问,不能双击文件用 file:// 协议,否则浏览器不会携带Cookie。

七、CSRF的防御方案
7.1 防御方案对比
防御方案    原理    
CSRF Token                    请求必须带随机暗号    
SameSite Cookie             浏览器禁止跨站带Cookie    
验证Referer                    检查请求来源
二次验证                           密码/验证码/人脸    
7.2 CSRF Token(最核心的防御)
原理
用户打开页面时,服务器生成随机Token

Token存入Session,同时返回前端

前端发请求时必须带上Token

后端对比请求Token vs Session Token

不一致 → 拒绝

7.3为什么攻击者拿不到Token?
同源策略           阻止攻击者偷走Token
高熵随机性    阻止攻击者猜出Token
生成方式
python
import secrets
# 生成256位随机Token
def generate_csrf_token():
return secrets.token_hex(32)  # → "a7f3c8e9d1b2..."
八、提问
Q1:简述CSRF攻击原理
攻击者诱导已登录的用户访问恶意页面,利用浏览器自动携带Cookie的特性,伪造用户请求执行非本意的操作。

Q2:CSRF和XSS的区别
XSS是网站本身有漏洞,黑客注入脚本;CSRF是网站接口设计缺陷,黑客借用用户身份发请求。XSS能偷Token,Token能防CSRF但防不住XSS。

Q3:如何防御CSRF?
核心三件套:①加CSRF Token验证;②设置SameSite Cookie;③关键操作二次验证(密码/验证码)。推荐组合:Token + SameSite=Lax。

Q4:Token为什么能防CSRF?
Token是随机暗号,存在页面里。同源策略阻止跨站脚本偷取,高熵随机性让攻击者无法猜测。攻击者既拿不到也猜不出。

Q5:Token放哪里最安全?
放在请求头里(如 X-CSRF-TOKEN)。不放Cookie(会被自动带),不放URL(会被日志记录)。

Q6:如果页面有XSS漏洞,Token还有用吗?
没用。XSS能在页面内部执行脚本,直接读取DOM里的Token。所以防御CSRF必须先防御XSS。

Q7:GET型CSRF和POST型CSRF哪个更容易?
GET型更容易,只需要一个<img>标签,不需要JavaScript。POST型需要少量JS自动提交表单。

Q8:为什么CSRF攻击要"跨站"?
如果不跨站(直接发链接),受害者会看到银行页面,攻击暴露。跨站后受害者看到的是伪装页面,攻击在背景里偷偷进行,全程无感知。

九、终极思维导图
CSRF(跨站请求伪造)

├── 原理
│   ├── 浏览器自动携带Cookie
│   └── 同源策略允许发请求但不允许读响应("只发不看")

├── 攻击条件(三个必须同时满足)
│   ├── ① 用户登录目标网站
│   ├── ② 目标网站只靠Cookie验证
│   └── ③ 黑客能构造请求

├── 攻击方式
│   ├── GET型(<img>标签,无需JS)
│   └── POST型(隐藏表单+JS自动提交)

├── 为什么需要跨站
│   ├── 隐藏攻击行为(伪装页面)
│   ├── 执行自动操作(POST需要JS)
│   └── 利用同源策略盲区

├── 防御方案
│   ├── CSRF Token 
│   │   ├── 生成:随机数
│   │   ├── 传递:请求头
│   │   └── 校验:对比Session
│   ├── SameSite Cookie 
│   │   ├── Strict:完全不跨站
│   │   └── Lax:部分跨站(默认)
│   └── 二次验证 
│       └── 密码/验证码/人脸

├── 相关概念
│   ├── 同源策略(SOP):协议+域名+端口
│   ├── Cookie:浏览器自动携带
│   └── XSS:CSRF的"放大器"

└── 代码审计(DVWA案例)
    ├── 漏洞:GET传参、无Token、无旧密码验证
    └── 攻击:<img>标签构造请求 + 404伪装
十,结语
CSRF是一个设计缺陷型漏洞,而非代码实现漏洞。理解它的关键在于理解浏览器的工作机制:

Cookie自动携带是HTTP协议规范,不是漏洞

同源策略允许跨站发请求是设计如此,不是疏忽

CSRF的根源是服务器无法区分"用户主动发起的请求"和"用户被诱骗发起的请求"

防御的核心就是给每个请求加上攻击者无法获取的动态参数(Token),让服务器有能力验证请求的真实性。
 

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐