关于Web前端安全防御CSRF攻防的几点考虑

一、CSRF 的工作原理

CSRF(Cross-Site Request Forgery,跨站请求伪造)是一种攻击方式,攻击者诱导用户在已登录目标网站的情况下,向该网站发送恶意请求,利用用户的身份凭证(如 Cookie)执行非预期操作(如转账、修改密码等)。

核心原理:

1.用户登录目标网站 A,网站 A 生成并存储用户的身份凭证(如 Session Cookie),浏览器保留该 Cookie。

2.攻击者诱导用户在未退出网站 A 的情况下,访问恶意网站 B(或点击包含恶意代码的链接)。

3.恶意网站 B 向网站 A 发送一个伪造的请求(如 POST /transfer),该请求会自动携带用户在网站 A 的 Cookie(浏览器的同源策略允许跨站请求携带 Cookie)。

4.网站 A 收到请求后,验证 Cookie 有效,误认为是用户本人操作,从而执行恶意请求。

示例场景:

用户登录银行网站后,被诱导点击一封邮件中的链接,该链接指向恶意网站,后者自动向银行发送 POST /transfer?to=攻击者账户&amount=1000 请求,由于浏览器自动携带银行 Cookie,银行会执行转账操作。

二、CSRF 与 XSS 的主要区别

|-------|------------------------------|--------------------|
| 维度 | CSRF | XSS |
| 攻击目标 | 利用用户的身份执行未授权操作(如修改数据) | 注入恶意脚本窃取信息或控制用户会话 |
| 技术核心 | 伪造跨站请求,依赖用户已登录状态 | 突破浏览器限制,执行恶意代码 |
| 与用户交互 | 无需用户输入,依赖诱导点击或自动请求 | 需将恶意脚本注入到目标网站并被执行 |
| 防御重点 | 验证请求来源的合法性(如 Token、SameSite) | 过滤 / 转义用户输入,防止脚本执行 |

SameSite 是 Cookie 的属性之一,用于限制跨站请求时 Cookie 的发送行为,从而阻断 CSRF 攻击中 Cookie 的自动携带。

1. 作用机制

当 Cookie 设置 SameSite 属性后,浏览器在跨站请求时会根据属性值决定是否携带该 Cookie,避免恶意网站利用用户的登录状态发起请求。

  • 当 Cookie 设置 SameSite 属性后,浏览器在跨站请求时会根据属性值决定是否携带该 Cookie,避免恶意网站利用用户的登录状态发起请求。

2. 不同取值(Strict/Lax)的适用场景

SameSite=Strict:

  • 规则:完全禁止跨站请求携带 Cookie。只有当请求的来源与目标网站完全同源(协议、域名、端口一致)时,Cookie 才会被携带。
  • 适用场景:安全性要求极高的操作,如支付、修改密码、转账等。例如,银行网站的核心功能需严格限制跨站请求,防止任何跨站场景下的身份滥用。

SameSite=Lax:

  • 规则:允许部分安全的跨站请求携带 Cookie,仅在 "导航类" 跨站请求(如点击链接 <a>、提交表单 <form>)中携带,禁止通过 XMLHttpRequest、fetch 等脚本发起的跨站请求携带。
  • 适用场景:兼顾安全性和用户体验的通用场景,如社交网站的分享功能(用户从第三方网站点击链接跳转回平台时,需携带登录状态)、电商网站的商品跳转等。大多数网站默认使用 Lax,平衡安全与可用性。

四、SPA 中结合 CSRF Token 与 CORS 策略实现跨域请求安全

SPA(单页应用)通常通过 AJAX 与后端跨域通信,需同时利用 CSRF Token(验证请求合法性)和 CORS(限制跨域权限)保障安全。

1. 核心思路

  • CSRF Token:后端为每个会话生成唯一 Token,要求前端请求时携带,后端验证 Token 有效性,确保请求由用户主动发起。
  • CORS:后端通过 HTTP 头限制允许的跨域来源、请求方法和 headers,防止未授权域名的跨域请求。

2. 具体实现步骤

步骤 1:后端生成并验证 CSRF Token

  • 用户登录后,后端生成 CSRF Token(存储在 Session 或 Redis 中,与用户会话关联)。
  • 前端通过接口(如 GET /csrf-token)获取 Token,存储在前端(如 localStorage 或内存中,不存储在 Cookie 中,避免被 CSRF 攻击利用)。

步骤 2:前端请求携带 Token

前端发起跨域请求(如 fetchaxios)时,在请求头(如 X-CSRF-Token)中携带 Token:

javascript 复制代码
fetch('https://api.example.com/action', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-CSRF-Token': localStorage.getItem('csrfToken') // 从前端存储中获取
  },
  body: JSON.stringify({ data: 'xxx' })
});

步骤 3:后端配置 CORS 策略

后端通过 Access-Control-Allow-* 头限制跨域权限,例如:

html 复制代码
Access-Control-Allow-Origin: https://spa.example.com  # 仅允许可信前端域名
Access-Control-Allow-Methods: POST, GET, OPTIONS      # 限制允许的请求方法
Access-Control-Allow-Headers: X-CSRF-Token, Content-Type  # 允许携带 Token 头
Access-Control-Credentials: true  # 允许跨域请求携带 Cookie(若需会话验证)

步骤 4:后端验证 Token 与 CORS

1.验证请求头中的 X-CSRF-Token 与后端存储的 Token 是否一致,不一致则拒绝请求。

2.检查请求来源是否在 Access-Control-Allow-Origin 列表中,不符合则拦截。

总结

  • CSRF 利用用户身份凭证伪造请求,与 XSS 的核心区别在于是否依赖注入脚本。
  • SameSite Cookie 通过限制跨站 Cookie 携带防御 CSRF,Strict 适用于高安全场景,Lax 兼顾体验。
  • SPA 中需结合 CSRF Token(验证请求合法性)和 CORS(限制跨域范围),确保跨域请求的安全性。
相关推荐
用户479492835691525 分钟前
mcp是怎么和大模型进行交互的,有哪些交互方式
前端·人工智能
凤年徐35 分钟前
解锁网页魔法:零基础HTML通关秘籍
前端·javascript·css·前端框架·html·web
PineappleCoder38 分钟前
防抖 vs 节流:高频事件的 “性能优化双雄” 怎么用?
前端·javascript·面试
小old弟38 分钟前
🤔面试官问你:什么是高阶函数?举例说明用到过的...
前端
是你的小橘呀39 分钟前
从小区广场舞群聊,看懂前端 er 必懂的发布订阅模式
前端
margicCode40 分钟前
0-1搭建项目基本配置(eslint+prettier)到release-it发布
前端
ZzMemory42 分钟前
CSS 命名太乱?BEM 规范帮你一键搞定,代码清爽到飞起!
前端·css·面试
大道小路43 分钟前
Vue3 组件数据传输小全
前端·javascript·vue.js
初辰ge43 分钟前
pCameraH5 v2.0:轻量级 H5 相机插件全新升级,支持拍照、录像与自定义水印
前端·javascript
Mr_Swilder44 分钟前
Chapter 8 Light and Color 光与颜色
前端