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

发布于:2025-08-03 ⋅ 阅读:(15) ⋅ 点赞:(0)

一、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 属性防御 CSRF

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

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

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-* 头限制跨域权限,例如:

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(限制跨域范围),确保跨域请求的安全性。

网站公告

今日签到

点亮在社区的每一天
去签到