1225 字
6 分钟
CSRF

1) 概念(核心定义)#

  • CSRF:攻击者诱导已登录目标站点的用户在其不知情的情况下向该站点发送一个合法请求,从而在目标站点上执行未授权操作(例如转账、修改邮箱、修改密码、提交表单等)。本质上利用了浏览器在跨站请求时会自动带上认证凭证(cookie、HTTP 验证头等)。

2) 成功发动 CSRF 的必要前提#

  1. 目标操作是基于浏览器自动附带凭证(通常是 cookie/session)的——服务器仅依赖 cookie 识别用户而不做额外校验

  2. 受害者必须在攻击触发时已对目标站点处于登录/认证状态(或具有足够权限)。

  3. 目标站点接受能被第三方页面构造并发送的 HTTP 请求(例如 GET/POST、图片加载、表单提交、AJAX 在 CORS 允许下等)。


3) 常见利用方式(#

  • GET 链接 /<img src>:如果有状态改变的 GET(错误用法),攻击者可用 <img src="https://target/transfer?to=attacker&amount=100"> 来触发。浏览器会发请求并带上 cookie。

  • 自动提交的表单:在恶意页面加入 <form action="https://target/..." method="POST">...<input type="submit"></form><script>form.submit()</script>。

  • 隐藏的跨站脚本(当 CORS 或浏览器策略允许时)或通过 fetch + credentials: 'include'(但普通跨站 fetch 默认受 CORS 限制)。

  • 邮件/论坛/远程图片/第三方 JS 注入:诱导点击或触发请求。 这些都是渗透测试常见的尝试方法。


4) 测试思路与检测要点#

  • 先识别“敏感动作”:修改密码、转账、增删用户、绑定邮箱等。标注哪些是 state‑changing。

  • 尝试无 token 的表单提交:在外站构造相同请求(img/form)看是否成功。

  • 查看响应/重定向:有无 CSRF token 校验失败提示、Referer/Origin 检查失败提示等。

  • 检查是否使用了 SameSite cookie 属性(Lax/Strict/None),以及其配置是否合理(如跨子域、多站点场景)

  • 尝试 XSS → CSRF 链接:如果存在 XSS,说明 CSRF token(若存在)可能被窃取,从而可绕过。

  • 测试 referer/origin 校验:在跨站请求中观察服务器是否验证 Origin 或 Referer 头(可通过构造请求或代理修改头模拟)。


5) 常见防御/缓解措施#

下面列出主流且实务中常用的防护措施,并标注优缺点与注意事项。

  1. 同步令牌(CSRF token / synchronizer token) — 最常见

  2. SameSite Cookie(浏览器端约束)

  3. 检查 Origin / Referer 头

  4. 双重提交 cookie(Double Submit Cookie)

  5. 避免把状态改变放在 GET

  6. 对 AJAX 请求要求自定义 header 并结合 CORS

  7. 最小权限与二次确认


6) 常见绕过方式#

  • XSS → 窃取/注入 token:如果存在 XSS,攻击者可读取页面中 token 或直接发起受害者上下文的请求,绕过 CSRF token。PortSwigger 有专门实验室说明。

  • 预测或复用弱 token:如果 token 生成不随机或与会话绑定不严,可能被猜到或重用。

  • 将敏感操作绑定在 GET:能被 <img>、CSS、script 标签等触发,防护难度大。

  • CORS / preflight 放宽错误配置:若服务端错误允许任意 origin 或误用 Access‑Control‑Allow‑Origin: * 与 Access-Control-Allow-Credentials: true 组合,会被滥用。


7) 渗透测试实用 payload 示例#

  • GET 示例(错误示范):
<img src="https://target.example.com/transfer?to=attacker&amount=100" />
  • 自动提交 POST 表单:
<form action="https://target.example.com/settings/email" method="POST">
<input name="email" value="attacker@example.com"/>
</form>
<script>document.forms[0].submit()</script>
  • 注意:现代浏览器的 fetch/XHR 跨域请求默认不带 cookie(除非 credentials: 'include')且受 CORS preflight 约束;所以在评估时要考虑这些限制。MDN/PortSwigger 有说明。

8) 渗透/评估时的系统化检查清单(快捷清单)#

  1. 列出所有 state‑changing endpoints(POST/PUT/DELETE 或存在“有效果”的 GET)。

  2. 对每个 endpoint:是否存在 CSRF token?token 来源是什么(cookie/body/header)?是否与会话绑定且不可预测?

  3. 检查 SameSite cookie 配置。

  4. 检查 Origin/Referer 校验是否存在且正确。

  5. 尝试用 <img>、自动提交表单、隐藏 iframe 发起请求(在受害者会话下)。

  6. 检查是否存在 XSS(因为 XSS 能破坏任何 CSRF 防护)。

  7. 检查 CORS 策略是否被放宽或误配置。

  8. 审查客户端 JS(是否把 token 放在可被第三方脚本读取的位置)。

(把上面逐条记录成表格进行复测很有效)


9) 防范#

  • 最高优先级:修复任何把敏感操作放到 GET 的接口;确保所有状态改变请求强制使用 POST/PUT/DELETE 并受 CSRF 保护。

  • 中高优先级:为所有敏感操作实现同步 token(并对所有 AJAX 请求检查 token);为 cookie 配置合适的 SameSite;对高风险操作加入二次确认。

  • 中优先级:启用并严格配置 Origin/Referer 校验(作为 token 的补充)。

  • 长期:定期做 XSS 审计(因为 XSS 可以使 CSRF 防护失效);在 CI 中把 CSRF 检测写成自动化测试用例(例如检查是否返回页面包含 token、是否对敏感 POST 缺 token 报错)。

CSRF
https://lab404.cn/posts/csrf/
作者
见山
发布于
2025-11-20
许可协议
CC BY-NC-SA 4.0