什么是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. 关键操作要确认(密码、短信二次验证)。
相关推荐
腾讯TNTWeb前端团队6 小时前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰9 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪9 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪9 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy10 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom11 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom11 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom11 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom11 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom11 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试