with one click
csrf-testing
检测 CSRF(跨站请求伪造)风险;当目标存在状态变更操作(密码修改、数据删除、转账、设置变更)时触发。
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
检测 CSRF(跨站请求伪造)风险;当目标存在状态变更操作(密码修改、数据删除、转账、设置变更)时触发。
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
白盒建模——一次深度建模产出五张共享模型:项目架构(技术栈/分层/框架自有封装/闭源依赖位置)、 入口点(路由/中间件信任边界)、认证与权限(会话/角色/多租户/归属字段)、业务(实体/流程状态机/ 业务不变量/高价值资产)、全局威胁(攻击面×漏洞类别的适用性映射,供下游逐一全测)。本能力不做漏洞判定,为后续 漏洞维度分析建立共享底图。
OS 命令注入综合检测——覆盖直接命令拼接 / shell 元字符 / 参数注入 / 间接 RCE,按回显 / 时间 / 带外通道分诊。 流量中参数值含主机名 / URL / 文件名 / 命令片段、响应里出现 shell 错误关键字(`/bin/sh` / `cmd.exe` / `command not found`)、注入 `sleep N` 耗时增加、上传后异步处理链路时使用。
文件上传多策略综合检测——覆盖扩展名 / MIME / 魔术数 / 解析漏洞 / 上传链组合(LFI / Zip Slip / SVG XSS / SVG XXE)。 流量含 multipart/form-data 上传、响应回显落盘路径、上传后文件可被 GET 解析、上传字段含 filename / path 可控时使用。
IDOR 水平越权检测 — 通过替换资源标识符(ID/UUID/路径)访问他人资源的风险;适用于用户资料、订单、文档、租户隔离场景。
检测路径穿越和本地文件包含(LFI)风险;当目标存在文件读取/下载/预览功能且含路径参数时触发;适用于文件下载、日志查看、模板加载等场景。
黑盒建模 — 迭代式攻击面建模,按站点级 / 页面级 / 功能级三粒度推进;进入新页面即触发一次页面级建模、切换新身份各刷新一次,产出端点账本与页面语义模型,为后续漏洞维度的适用性判断提供依据。
| name | csrf-testing |
| description | 检测 CSRF(跨站请求伪造)风险;当目标存在状态变更操作(密码修改、数据删除、转账、设置变更)时触发。 |
| when-to-use | 当目标存在状态变更操作(密码修改、数据删除、转账、设置变更)且依赖 Cookie 自动鉴权时 |
| allowed-tools | bash,read_file,list_files,rg |
| user-invocable | false |
跨站请求(受害者已登录,浏览器自动携带 Cookie)→ 状态变更端点(服务端依赖 Cookie 自动鉴权且不验证请求来源 / 不要求 CSRF token / SameSite 防护缺失)= CSRF 跨站请求伪造。一句话讲清成因:状态变更操作只检查"是否已登录"而不检查"操作是否由本站发起",攻击者借受害者会话从外部站点发出请求即可触发越权写操作。业务命名不可作筛选——不能用"这是设置接口/这是支付接口"作为是否检测的依据;CSRF 关注的是所有改变服务端状态的端点(POST / PUT / DELETE / PATCH,以及触发状态变更的 GET),按 sink 语义(是否依赖 Cookie 自动鉴权 + 是否缺乏来源验证)判断,不按业务命名筛选。详见同根目录 pentest/web-security-testing/SKILL.md 漏洞成因图谱 · CSRF 行(不在本 skill 重复成因)。
以下是已知的常见 CSRF 触发线索,作为基线起点而非必检硬清单:
[x] done[-] n/a (原因)[+] added (来源)基线触发线索按"sink 语义"分类(不按业务命名):
SameSite 或为 SameSite=None。/api/delete?id=、/logout?confirm=1、/follow?user=、邮件订阅退订链接);这种最容易被忽略,但 CSRF 通过 <img src> 即可触发。evil.target.com 仍接受。@PostMapping / app.post(...) 中处理状态变更但缺少 CSRF middleware;Spring 关闭 csrf().disable();Django @csrf_exempt;Express 未引入 csurf。加载本 skill 时按这些问题思考:
http://app.com:8080 vs http://app.com:8081)、同站不同子域 (evil.app.com vs target.app.com)在某些浏览器和配置下不被视为跨站。common/closure-verification.md 的《破坏性 / 不可逆动作的闭环边界》执行——回读证明改走哨兵自证或非破坏差分,二者都做不到就停 suspected,禁止对真实业务数据执行破坏动作来强行闭环。检查目标是否具备 CSRF 防护:
csrf_token、_token、authenticity_token、__RequestVerificationToken);请求头中是否要求 X-CSRF-Token。Set-Cookie 响应头是否包含 SameSite=Strict / SameSite=Lax / SameSite=None。X-Requested-With: XMLHttpRequest 等浏览器跨站不自动携带的自定义头。application/json(浏览器表单跨站发不出 JSON 加预检 CORS)。| 防护机制 | 绕过尝试 |
|---|---|
| CSRF Token | 移除 token 参数、使用空值、使用另一用户的 token、使用过期 token、token 仅校验存在不校验值 |
| SameSite=Lax | 顶层导航 GET 触发;同站不同端口 / 同站不同子域 POST 触发;form 表单中 method 为 GET 时 Lax 不拦截 |
| Referer 校验 | 移除 Referer (<meta name="referrer" content="no-referrer">);Referer 中含 target 域名子串绕过 |
| Origin 校验 | 子域 Origin、空 Origin、null Origin |
| 自定义 Header | 简单请求绕过(form-data / text/plain 不触发预检 CORS) |
构造最小 CSRF PoC 页面:
<form action="TARGET_URL" method="POST">
<input type="hidden" name="param1" value="value1">
<input type="submit" value="Submit">
</form>
<script>document.forms[0].submit();</script>
对 GET 副作用端点用 <img src="TARGET_URL"> 即可触发。
不可逆动作例外:状态变更若为删除/转账/不可逆动作,不得在受害者真实数据上执行;改用受害者名下哨兵数据或非破坏差分证明,按
common/closure-verification.md《破坏性 / 不可逆动作的闭环边界》,做不到则降suspected。
http.csrf().disable() + Cookie 鉴权的 /api/user/email POST — 经典 token 缺失(cookie-auth-state-change-no-token)/api/delete?id=123 用 GET 且只看登录态 — GET 副作用 + 图片标签即可触发(get-side-effect-csrf)SameSite=Lax 当万能防护,未额外验证;evil.target.com:8080 向 app.target.com:443 发 POST 仍被处理(samesite-lax-cross-port-bypass)if ("target.com" in request.headers.get("Referer", "")) — Referer: http://attacker.com/target.com.html 即可绕过(referer-check-empty-bypass)以下是 CSRF 维度的典型窄化误判:
@csrf_exempt 或忘记加 middleware;必须按端点独立验证。text/plain + body 拼成 JSON 字符串、Flash / XHR 旧绕过、CORS 配置过宽都可能突破;不能只看 Content-Type 推断。为什么这里是「必须」:反例义务属于交付契约——"该子系统无 CSRF"或"已防护"结论是覆盖完整性的产物声明,缺失反向验证清单会让下游误信"该维度全站安全"。
写"未发现 CSRF"或"已防护"前,产物必须包含:
清单不完整 → 结论降级为 partial-coverage 并显式声明未覆盖范围。
特别警示:最容易漏的是"GET 副作用端点"和"已测 cookie 鉴权端点就跳过 Authorization 鉴权端点"。前者用 <img> 即可触发;后者在前端把 token 写入 cookie 再回填 Authorization 的模式下仍可能存在跨站路径。
通用闭环口径见同根目录 common/closure-verification.md(技能表 path 列同一抽取根下,需要时 read_file 读取)。核心:完整证据链才判 confirmed,中间信号最多 suspected。本漏洞特有要点:
| 现象 | 判定 |
|---|---|
| 跨站请求成功触发状态变更,通过回读确认生效 | confirmed |
| 缺少 CSRF Token 但有 SameSite Cookie 或其他防护,未实际验证 | suspected |
| CSRF Token 有效、SameSite=Strict、且绕过尝试均失败且覆盖完整 | not vulnerable |
| 覆盖清单不完整(如未测 GET 副作用 / 未测同站不同端口 SameSite 绕过 / 未跨子系统) | partial-coverage |
不可逆动作例外:上表 confirmed 行的状态变更若为删除/转账/不可逆动作,按
common/closure-verification.md《破坏性 / 不可逆动作的闭环边界》——回读改用哨兵数据或非破坏差分,不得对受害者真实数据真执行,做不到则降suspected。
SameSite=Strict(敏感操作)或 SameSite=Lax(普通操作);明确禁止 SameSite=None 除非搭配额外 CSRF token。Origin 和 Referer 头,按域名结构解析,不接受空值。