什么是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. 关键操作要确认(密码、短信二次验证)。
相关推荐
香香爱编程17 小时前
electron对于图片/视频无法加载的问题
前端·javascript·vue.js·chrome·vscode·electron·npm
程序猿_极客18 小时前
【期末网页设计作业】HTML+CSS+JavaScript 蜡笔小新 动漫主题网站设计与实现(附源码)
前端·javascript·css·html·课程设计·期末网页设计
zl_vslam18 小时前
SLAM中的非线性优-3D图优化之轴角在Opencv-PNP中的应用(一)
前端·人工智能·算法·计算机视觉·slam se2 非线性优化
CDwenhuohuo19 小时前
用spark-md5实现切片上传前端起node模拟上传文件大小,消耗时间
前端
阿桂有点桂19 小时前
React使用笔记(持续更新中)
前端·javascript·react.js·react
自由日记19 小时前
实例:跳动的心,火柴人
前端·css·css3
柯腾啊19 小时前
一文简单入门 Axios
前端·axios·apifox
im_AMBER19 小时前
React 15
前端·javascript·笔记·学习·react.js·前端框架
How_doyou_do20 小时前
模态框的两种管理思路
java·服务器·前端
snow@li20 小时前
前端:前端/浏览器 可以录屏吗 / 实践 / 录制 Microsoft Edge 标签页、应用窗口、整个屏幕
前端·浏览器录屏·前端录屏·web录屏