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

文章目录 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,请回答:
浏览器是否可能发送请求并携带登录 Cookie?
攻击页面能否读取接口响应?不能读取是否代表攻击失败?
同源策略和 CORS 能否直接防止这次攻击?
应为接口设计哪些 CSRF 防护措施?
将 Cookie 改成
SameSite=Lax或SameSite=Strict后,风险有什么变化?是否还需要其他防护?
我的回答
完全有可能,脚本会自动发送一个修改邮箱的 POST 请求。
攻击页面不能读取响应,但脚本可以不断触发接口,因此也算攻击成功。
同源策略和 CORS 不能防止,因为接口没有设置 CSRF Token,也没有校验请求来源。
限制请求次数。
不明白。
面试点评
总分 :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,即跨站请求伪造。
它利用了两个条件:
用户已经登录目标网站。
浏览器会自动为符合条件的目标请求携带 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 响应头,攻击脚本通常不能读取响应,但已经发送的请求及其副作用不会因此自动撤销。
4. Cookie 属性分别解决什么问题
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 文档
一般含义如下:
配置 | 一般行为 |
|---|---|
| 跨站请求通常不携带 Cookie,限制最强 |
| 同站请求携带;跨站顶层安全导航可能携带,普通跨站 POST 通常不携带 |
| 允许跨站携带,但必须同时设置 |
需要注意:
没有显式设置
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.test7. 敏感操作需要更强验证
修改邮箱、密码、支付信息等操作可能影响账号控制权。即使已经使用 CSRF Token,也可以进一步要求:
重新输入密码。
短信或邮箱验证码。
WebAuthn 等强认证。
操作确认页面。
向原邮箱发送安全通知。
为敏感操作记录审计日志。
这些措施属于高风险操作的纵深防御。
8. 推荐的组合方案
会话 Cookie 可以采用:
Set-Cookie: __Host-session=abc123;
Path=/;
Secure;
HttpOnly;
SameSite=Lax状态变更接口同时实施:
SameSite Cookie
+ CSRF Token
+ Origin 校验
+ 正确的 HTTP 方法
+ 敏感操作二次认证
+ 限流与审计不同措施解决不同风险,不能互相简单替代。
名词解释
Cookie
浏览器保存的一小段数据。符合域名、路径、安全和 SameSite 等条件时,浏览器会自动将其附加到请求中。
Session Cookie
用于标识登录会话的 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 防护相关文章
- 面试题-基础
Vue 3 响应式解构:为什么替换 user 后出现“李四 / 王五”
通过一道 Vue 3 代码题,区分 reactive 对象解构、嵌套属性修改与对象替换的行为,并用 toRef 保持源属性关联。文章保留首次作答及追问补答,说明从误判到纠正的过程。
- 面试题-基础
JavaScript 浅拷贝、深拷贝与 structuredClone:前端状态更新的正确方式
通过一道对象复制代码题,梳理 JavaScript 浅拷贝、JSON 深拷贝、structuredClone 和 transferable object 的边界,并解释 React 结构共享与 Vue 3 响应式更新的差异。
- 面试题-基础
面试题:AI 前端中的模型 API Key 安全
本题考察模型调用链路设计,以及前端环境变量、BFF 和接口安全。
评论
0 条评论会在审核后展示,邮箱不会公开。