什么是csrf攻击?如何进行防御?

什么是 CSRF(跨站请求伪造攻击)?


1. 定义

CSRF(Cross-Site Request Forgery) 是攻击者诱导用户在已登录目标网站的情况下,访问恶意页面或链接,从而以用户的身份向目标网站发起非预期的请求(如转账、修改密码等)。

  • 核心问题:浏览器会默认携带用户的 Cookie(如登录凭证),攻击者利用这一点伪造用户身份操作。

2. 攻击流程

  1. 用户登录信任的网站(如 bank.com),服务器返回登录凭证(Cookie)。
  2. 用户访问攻击者的恶意页面(如钓鱼邮件中的链接)。
  3. 恶意页面自动向 bank.com 发送请求(如转账操作),浏览器自动携带用户的 Cookie。
  4. 服务器认为这是用户的合法操作,执行请求。

示例

html 复制代码
<!-- 恶意页面中隐藏的转账请求 -->
<img src="https://bank.com/transfer?to=hacker&amount=100000" />

3. CSRF 攻击类型

类型 触发方式 示例
GET 型 通过 imgiframesrc 属性自动发送 GET 请求。 <img src="https://bank.com/delete-account?id=123" />
POST 型 构造隐藏的表单,页面加载时自动提交 POST 请求。 恶意页面中隐藏 <form action="https://bank.com/transfer" method="POST">
链接型 诱导用户点击伪装的链接(如短链),触发请求。 <a href="https://bank.com/reset-password">点击抽奖</a>

4. 防御措施

(1) 同源检测

  • 检查 RefererOrigin
    验证请求是否来自合法的源(如只允许本站的域名)。
    • 缺点:某些浏览器可能不发送 Referer,或存在被篡改的风险。

(2) CSRF Token

  • 原理
    在表单或请求参数中添加一个随机 Token(服务器生成并存储在 Session 或 Cookie 中),提交时验证 Token 是否匹配。
    • 关键点:Token 需足够随机(如 UUID),且仅对当前会话有效。
    • 实现步骤
      1. 服务器生成 Token,返回给前端(如写入页面隐藏字段)。
      2. 前端提交请求时携带 Token(如参数或请求头)。
      3. 服务器校验 Token 的有效性。
  • 设置 Cookie 的 SameSite 属性,限制第三方网站发送 Cookie:

    http 复制代码
    Set-Cookie: sessionID=abc123; SameSite=Strict
    • Strict:禁止第三方网站携带 Cookie(如银行场景)。
    • Lax:允许安全方法(如 GET)的跨站请求携带 Cookie(默认值)。
    • None :允许所有跨站请求携带 Cookie(需配合 Secure 属性)。
  • 前端在请求参数中额外携带 Cookie 中的某个字段(如 sessionID),服务器校验参数与 Cookie 中的值是否一致。
    • 缺点:若网站存在 XSS 漏洞,Cookie 可能被窃取。

(5) 自定义请求头

  • 前端在 AJAX 请求中添加自定义头(如 X-Requested-With: XMLHttpRequest),服务器仅接受带此头的请求。
    • 仅适用于 API 请求,普通表单无法自动添加此头。

(6) 增加二次验证

  • 对敏感操作(如支付、修改密码)要求用户二次确认(如输入密码、短信验证码)。

5. CSRF 与 XSS 的区别

特性 CSRF XSS
攻击目标 利用用户的登录状态发起伪造请求。 窃取用户数据或劫持会话。
依赖条件 用户需已登录目标网站。 目标网站存在未转义的恶意脚本输入。
防御重点 Token、SameSite Cookie、Referer 检查。 输入过滤、输出转义、CSP。

6. 面试回答示例

"CSRF 是攻击者利用用户已登录的状态,诱导用户访问恶意页面,伪造请求以用户身份执行操作(如转账)。防御方法包括 CSRF Token、设置 SameSite Cookie、校验 Referer 头,以及敏感操作增加二次验证。"


快速记忆口诀

防 CSRF 三步曲:

  1. Token 随身带(请求携带随机 Token)。
  2. Cookie 锁来源(SameSite=Strict/Lax)。
  3. 关键操作要确认(密码、短信二次验证)。
相关推荐
2401_884810744 分钟前
Vue3笔记
前端·vue.js·笔记
小画家~14 分钟前
第二十四:5.2【搭建 pinia 环境】axios 异步调用数据
前端·vue.js
codexu17 分钟前
Tauri跨端笔记实战(4) - 如何实现系统级截图
前端·前端框架·开源
过期生抽_21 分钟前
如何快速上手Pinia!
前端
程序员黄同学31 分钟前
请解释 React 中的 Hooks,何时使用 Hooks 更合适?
前端·javascript·react.js
六个点2 小时前
路由hash和history的实现
前端·javascript·面试
音仔小瓜皮2 小时前
【Electron入门】进程环境和隔离
前端·javascript·electron
JIU_WW2 小时前
Netty内置的空闲检测机制
java·服务器·前端·websocket·netty
onejason2 小时前
反向海淘的API接口:技术赋能与代码示例
前端
蒜香拿铁2 小时前
react进阶
前端·react.js