跳到主要内容
← 返回文章列表
面试题-基础2026/09/07约 9 分钟读完

Cookie 登录接口中的 CSRF:同源策略、CORS、SameSite 与 CSRF Token

通过修改邮箱的跨站表单攻击,梳理 CSRF 的成立条件,解释为什么“读不到响应”不代表攻击失败,并比较 SameSite、CSRF Token、Origin 校验与限流的职责边界。

Cookie 登录接口中的 CSRF:同源策略、CORS、SameSite 与 CSRF Token
文章目录 34

题目信息

  • 领域 :浏览器、网络与安全

  • 难度 :L2 基础应用(中级偏低)

  • 题型 :场景题

  • 预计用时 :10–15 分钟

  • 考察方向 :理解 Cookie 自动携带、同源策略、CORS 和 CSRF,并能为状态变更接口设计合理的防护措施。

面试题

某后台系统使用 Cookie 保存登录会话:

Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=None

修改用户邮箱的接口如下:

POST https://admin.example.com/api/profile/email
Content-Type: application/x-www-form-urlencoded

email=attacker@example.com

接口只检查 session Cookie,没有 CSRF Token,也没有校验请求来源。

攻击者在 evil.example 页面中放置了自动提交的表单:

<form
  method="POST"
  action="https://admin.example.com/api/profile/email"
>
  <input
    type="hidden"
    name="email"
    value="attacker@example.com"
  />
</form>

<script>
  document.querySelector("form").submit();
</script>

假设用户已经登录 admin.example.com,请回答:

  1. 浏览器是否可能发送请求并携带登录 Cookie?

  2. 攻击页面能否读取接口响应?不能读取是否代表攻击失败?

  3. 同源策略和 CORS 能否直接防止这次攻击?

  4. 应为接口设计哪些 CSRF 防护措施?

  5. 将 Cookie 改成 SameSite=Lax 或 SameSite=Strict 后,风险有什么变化?是否还需要其他防护?

我的回答

  1. 完全有可能,脚本会自动发送一个修改邮箱的 POST 请求。

  2. 攻击页面不能读取响应,但脚本可以不断触发接口,因此也算攻击成功。

  3. 同源策略和 CORS 不能防止,因为接口没有设置 CSRF Token,也没有校验请求来源。

  4. 限制请求次数。

  5. 不明白。

面试点评

  • 总分 :30 / 100

  • 正确性 :14 / 40

  • 原理理解 :5 / 20

  • 工程应用 :3 / 20

  • 边界与权衡 :2 / 10

  • 面试表达 :6 / 10

正确点

  • 判断跨站表单可能发出修改邮箱请求。

  • 知道攻击页面通常无法读取跨域响应。

  • 意识到无法读取响应不代表状态变更没有发生。

  • 注意到了接口缺少 CSRF Token 和来源校验。

遗漏点

分析 CSRF 时,需要独立判断四件事:

请求能否发送
-> 身份凭证是否携带
-> 响应能否读取
-> 服务端是否执行操作

原回答没有说明:

  • SameSite=None 对跨站 Cookie 携带的影响。

  • HTML 表单为什么可以发出跨源请求。

  • 同源策略和 CORS 主要限制什么。

  • SameSite、CSRF Token 和来源校验如何防御 CSRF。

  • HttpOnly、Secure 为什么不能直接防御 CSRF。

错误点

攻击成功不依赖无限触发

攻击者只要让浏览器成功发送一次携带用户身份凭证的请求,并使服务端修改邮箱,CSRF 就已经成功。

攻击者不需要:

  • 读取用户的 Cookie。

  • 读取接口响应。

  • 无限重复请求。

限流不是主要 CSRF 防护

限流只能限制操作频率。例如接口一分钟只允许修改一次邮箱,攻击者仍可能利用这一次机会完成攻击。

它不能判断请求来自合法页面还是攻击页面,因此只能作为补充措施。

推荐答案

本题中的跨站表单请求可能被浏览器发送。由于会话 Cookie 设置了 SameSite=None; Secure,在题设假设下,Cookie 可能随跨站请求自动携带,服务端便可能把攻击请求识别为已登录用户的操作。

同源策略通常会阻止攻击页面读取接口响应,但不会阻止 HTML 表单进行跨源提交。修改邮箱属于有副作用的操作,即使攻击者读不到响应,只要服务端执行了修改,攻击就已经成功。

CORS 主要控制浏览器是否允许脚本读取跨源响应,并不能替代 CSRF 防护。服务端应该组合使用合适的 SameSite 策略、CSRF Token、Origin 或 Referer 校验,并对修改邮箱等敏感操作增加重新认证或二次确认。限流只能作为辅助防护。

在现代浏览器的一般行为下,显式设置 SameSite=Lax 后,Cookie 通常不会随普通跨站 POST 表单提交;Strict 的限制更强,但也可能影响用户从外部链接进入网站后的登录体验。SameSite 仍应被视为纵深防御,不能在所有系统中完全替代服务端校验。

相关知识点补全

1. CSRF 的本质

CSRF,全称 Cross-Site Request Forgery,即跨站请求伪造。

它利用了两个条件:

  1. 用户已经登录目标网站。

  2. 浏览器会自动为符合条件的目标请求携带 Cookie。

攻击者不需要知道 Cookie 的值。攻击者只需要诱导用户浏览器向目标网站发出一个有副作用的请求。

用户登录银行网站
-> 浏览器保存登录 Cookie
-> 用户访问攻击页面
-> 攻击页面构造转账请求
-> 浏览器可能自动携带银行 Cookie
-> 银行误以为请求来自用户

2. 同源策略为什么没有阻止表单提交

源由三部分组成:

协议 + 主机 + 端口

以下两个地址不是同源:

https://evil.example
https://admin.example.com

同源策略通常限制跨源读取,但链接跳转、重定向和表单提交等跨源写入通常允许。攻击页面可能无法读取响应,但请求仍能到达服务端。MDN 对同源策略的说明

因此需要区分:

跨源请求被发送
≠ 攻击页面能够读取响应

3. 为什么 CORS 不能直接防止本题攻击

本题请求满足传统“简单请求”的条件:

POST
Content-Type: application/x-www-form-urlencoded

这类请求可以由 HTML 表单跨源提交,不要求先通过 CORS 预检。服务端仍必须主动防御 CSRF。MDN CORS 文档

如果目标服务器没有允许攻击源的 CORS 响应头,攻击脚本通常不能读取响应,但已经发送的请求及其副作用不会因此自动撤销。

HttpOnly

HttpOnly

作用:禁止前端 JavaScript 通过 document.cookie 读取该 Cookie。

主要用于降低 XSS 窃取会话 Cookie 的风险。

它不能阻止浏览器自动携带 Cookie,因此不能单独防止 CSRF。

Secure

Secure

作用:Cookie 只通过 HTTPS 连接发送。

它防止 Cookie 通过普通 HTTP 明文传输,但不能判断请求来自合法页面还是攻击页面。

SameSite

SameSite=Strict
SameSite=Lax
SameSite=None

作用:控制 Cookie 是否可以随跨站请求发送。MDN Set-Cookie 文档

一般含义如下:

配置

一般行为

Strict

跨站请求通常不携带 Cookie,限制最强

Lax

同站请求携带;跨站顶层安全导航可能携带,普通跨站 POST 通常不携带

None

允许跨站携带,但必须同时设置 Secure

需要注意:

  • 没有显式设置 SameSite 时,现代浏览器通常按 Lax 处理。

  • 浏览器可能进一步限制第三方 Cookie,即使设置了 SameSite=None,也不保证所有环境都一定携带。

  • SameSite 判断的是“同站”,不完全等于“同源”。

  • 某些同站子域名风险、错误的 GET 状态变更接口和旧浏览器行为仍可能绕过单一防线。

因此,OWASP建议在多数系统中把 SameSite 作为纵深防御,与 Token 或其他服务端校验组合使用。OWASP CSRF 防护指南

5. CSRF Token 如何工作

服务端生成一个攻击者无法预测的 Token,并把它提供给合法页面。

合法页面提交状态变更请求时,同时提交该 Token:

POST /api/profile/email
Cookie: session=abc123
X-CSRF-Token: random-secret-token

服务端验证:

登录 Cookie 有效
并且
CSRF Token 正确

攻击网站可能让浏览器自动携带 Cookie,但通常无法获取合法页面中的 CSRF Token,因此不能构造有效请求。

Token 应满足:

  • 与用户会话关联。

  • 足够随机且不可预测。

  • 由服务端验证。

  • 不放在容易泄露的 URL 中。

  • 验证失败时拒绝状态变更请求。

OWASP推荐的常见方案包括同步 Token 模式和正确实现的 Double Submit Cookie 模式。OWASP CSRF Token 指南

6. Origin 与 Referer 校验

浏览器请求可能携带:

Origin: https://admin.example.com

服务端可以为状态变更接口检查:

Origin 是否属于允许的精确来源

如果没有 Origin,可以根据明确策略辅助检查 Referer。

校验时应比较完整来源:

协议 + 主机 + 端口

不能使用容易误判的字符串包含判断:

// 错误示意
origin.includes("example.com");

否则类似下面的攻击域名可能被错误放行:

https://example.com.attacker.test

7. 敏感操作需要更强验证

修改邮箱、密码、支付信息等操作可能影响账号控制权。即使已经使用 CSRF Token,也可以进一步要求:

  • 重新输入密码。

  • 短信或邮箱验证码。

  • WebAuthn 等强认证。

  • 操作确认页面。

  • 向原邮箱发送安全通知。

  • 为敏感操作记录审计日志。

这些措施属于高风险操作的纵深防御。

8. 推荐的组合方案

会话 Cookie 可以采用:

Set-Cookie: __Host-session=abc123;
  Path=/;
  Secure;
  HttpOnly;
  SameSite=Lax

状态变更接口同时实施:

SameSite Cookie
+ CSRF Token
+ Origin 校验
+ 正确的 HTTP 方法
+ 敏感操作二次认证
+ 限流与审计

不同措施解决不同风险,不能互相简单替代。

名词解释

浏览器保存的一小段数据。符合域名、路径、安全和 SameSite 等条件时,浏览器会自动将其附加到请求中。

用于标识登录会话的 Cookie。服务端根据它判断当前请求属于哪个用户。

CSRF

跨站请求伪造。攻击者利用用户已有登录状态,诱导浏览器向目标网站发送非用户本意的状态变更请求。

Origin

请求来源,由协议、主机和端口组成:

https://admin.example.com:443

同源策略

浏览器安全机制,主要限制一个源的页面读取或操作另一个源的资源。跨源表单提交等写入行为通常仍然允许。

CORS

Cross-Origin Resource Sharing,跨源资源共享。服务器通过响应头声明哪些来源可以让浏览器脚本读取跨源响应。

它不是用户身份认证机制,也不能替代 CSRF 防护。

简单请求

满足特定方法、请求头和 Content-Type 条件的跨源请求,不会先发送 CORS 预检。

HTML 表单常见的以下请求属于这一类:

POST
Content-Type: application/x-www-form-urlencoded

预检请求

浏览器在某些跨源请求前发送的 OPTIONS 请求,用来询问服务器是否允许真实请求。

SameSite

Cookie 属性,用于控制 Cookie 是否随跨站请求发送,可选值包括 Strict、Lax 和 None。

HttpOnly

Cookie 属性,阻止页面 JavaScript 读取 Cookie。它主要降低 Cookie 被 XSS 脚本窃取的风险,不阻止浏览器自动发送 Cookie。

Secure

Cookie 属性,要求 Cookie 仅通过 HTTPS 发送。

CSRF Token

服务端生成的不可预测值,用于证明状态变更请求来自合法页面,而不是只有登录 Cookie 的跨站伪造请求。

状态变更接口

会修改服务端数据或产生业务副作用的接口,例如:

  • 修改邮箱

  • 修改密码

  • 删除数据

  • 创建订单

  • 转账

  • 修改权限

此类操作不应由 GET 请求执行。

限流

限制用户、IP 或接口在一定时间内的请求次数。它能降低暴力请求和资源滥用,但不能证明请求来自合法页面。

XSS

Cross-Site Scripting,跨站脚本攻击。攻击者使恶意 JavaScript 在目标网站自身的上下文中执行。

XSS 与 CSRF 不同,但成功的 XSS 往往可以读取页面数据或代替用户发起合法格式的请求,从而削弱许多 CSRF 防护。

最终总结

判断 CSRF 不能只问“是否跨域”,而要依次分析:

请求能否发送?
Cookie 是否会自动携带?
攻击者能否读取响应?
服务端是否验证请求来源?
接口是否产生状态变更?

本题的核心结论是:

读不到响应
≠ 请求没有发送
≠ 服务端没有执行

各项机制的职责是:

HttpOnly
-> 防止 JavaScript 读取 Cookie

Secure
-> 限制 Cookie 通过 HTTPS 发送

SameSite
-> 限制跨站请求携带 Cookie

同源策略与 CORS
-> 主要限制跨源响应读取

CSRF Token、Origin 校验
-> 验证状态变更请求的合法来源

限流
-> 降低滥用频率,但不能替代 CSRF 防护

评论

0 条

评论会在审核后展示,邮箱不会公开。

正在确认登录状态

5000 / 5000