iframe本身不触发CSRF,但可作为攻击载体:攻击者嵌入恶意页面,利用浏览器自动携带Cookie的特性,通过img、form或脚本向目标站发起请求,服务端误判为合法操作;防御须服务端校验绑定会话的CSRF Token,并配合SameSite Cookie与iframe沙箱隔离。

iframe本身不触发CSRF,但会成为CSRF攻击的载体
iframe 标签本身不会“发起” CSRF 攻击,但它常被用作攻击跳板:攻击者把恶意页面嵌入 iframe,诱导用户在已登录目标站的前提下访问该页,再通过 <img>、<form> 或自动脚本向目标站发请求——浏览器照常带上 Cookie,服务端误判为合法操作。
关键点在于:同源策略不限制 <img>、<script>、<iframe> 的跨域加载,只限制 JS 读取响应内容。所以攻击者根本不需要读回数据,只要让请求发出去并生效就行(比如删账号、转账、改邮箱)。
- 常见错误现象:后台日志里看到大量来自第三方域名的 POST 请求,但没走自己表单逻辑
- 容易忽略的场景:管理后台嵌了合作方的 iframe 统计面板,对方页面被黑后注入恶意 form 自动提交
- 防御不能只盯 iframe 标签,得从请求发起源头和服务端验证双管齐下
服务端必须校验 CSRF Token,且 Token 要绑定会话
仅靠前端禁止 iframe 加载(如 X-Frame-Options)只能防点击劫持,对 CSRF 无效——因为 CSRF 不依赖 iframe 渲染,它靠的是浏览器自动携带 Cookie 的行为。
真正起作用的是服务端对每个敏感请求强制校验 Token:
立即学习“前端免费学习笔记(深入)”;
-
__RequestVerificationToken(ASP.NET)或_xsrf(Tornado)这类字段必须存在且匹配当前会话生成的密文 - Token 不能全局复用,必须和用户 session ID 强绑定;否则攻击者可先访问一次登录页拿到 token,再构造请求重放
- GET 请求也建议加 token 防御(尤其含状态变更的 GET,如
/api/user/delete?id=123),别只防 POST - 若用 AJAX 提交,需手动从
input[name="__RequestVerificationToken"]或 cookie 中取值,并塞进headers: { 'RequestVerificationToken': token }
前端配合:SameSite Cookie + iframe 沙箱隔离
服务端生成 Cookie 时加上 SameSite=Strict 或 SameSite=Lax,能大幅降低浏览器自动携带 Cookie 发起跨站请求的概率。但注意:SameSite=Lax 对 POST 表单提交仍可能放行,不能替代 Token。
对于必须嵌入的第三方 iframe,启用沙箱属性可限制其能力:
-
<iframe src="https://partner.com/widget" sandbox="allow-scripts">—— 默认禁用表单提交、脚本执行、插件等 - 去掉
allow-forms就能阻止 iframe 内部自动提交表单(也就断了最常见 CSRF 路径) - 避免写成
sandbox=""(空值 = 全禁),也不要用allow-same-origin,否则沙箱失效
AJAX 请求绕过 iframe 的 CSRF 防御陷阱
前后端分离架构下,[ValidateAntiForgeryToken] 在 ASP.NET 中默认只校验 Content-Type: application/x-www-form-urlencoded 和 multipart/form-data 的 form post 请求,对 application/json 的 AJAX 请求直接跳过校验。
这意味着你写了 [ValidateAntiForgeryToken],但前端用 fetch(..., { method: 'POST', headers: { 'Content-Type': 'application/json' } }),token 校验就形同虚设。
- 正确做法:换用
[AutoValidateAntiforgeryToken](ASP.NET Core)或自定义过滤器,统一拦截所有 POST/PUT/DELETE 请求 - 或者,强制 AJAX 请求也走 form-data 格式,把 token 放在 body 里,而非 header
- Tornado 用户注意:
xsrf_cookies: True仅对带_xsrf字段的请求生效,JSON 请求必须手动解析 header 中的X-XSRF-TOKEN
CSRF 防御最易被忽略的点是 Token 生命周期与会话解耦——比如 token 存 Redis 却没关掉滑动过期,或前端缓存了旧 token 多次复用。一旦 token 可预测、可重放、可跨用户共享,整个防御就塌了。



















