ZAP代理PHP站点只需配置浏览器指向其默认代理端口127.0.0.1:8080,确保Proxy运行正常;CSRF检测需人工验证token存在性、校验逻辑及可复用性,ZAP主动扫描效果有限;抓不到token常因JS动态生成,需启用Headless Browser或分析XHR接口。
ZAP 本身不区分后端语言,它只抓 HTTP 流量;只要 PHP 站能被你本地浏览器访问,ZAP 就能代理它。关键不是“PHP 特殊配置”,而是确保浏览器流量真走 ZAP 的代理端口(默认 127.0.0.1:8080)。
实操要点:
Tools → Options → Local Proxy 确认监听地址和端口(别改成本机外网 IP,否则可能被防火墙拦截)127.0.0.1:8080;Chrome 推荐用 SwitchyOmega 插件快速切换,避免全局污染Quick Start 标签页点 Automated Scan 或手动输入 URL 进 Manual Explore,否则 ZAP 不会主动记录请求Proxy is running,以及浏览器是否报 ERR_PROXY_CONNECTION_FAILED —— 多半是端口被占用或代理没开CSRF 检测不靠 ZAP 自动扫描“打分”,而要人工验证表单行为是否缺失抗抵赖机制。ZAP 的 Active Scan 对 CSRF 效果有限,真正有效的是看请求里有没有 CSRF token、是否校验、能否复用。
操作路径:
Sites 树里找到目标 PHP 页面的 POST 请求(比如 /admin/update_profile.php)Resend with Request Editor,删掉 Cookie 头或修改 Referer,看响应是否仍成功(若成功,说明没校验来源)token=abc123 或 _csrf=xyz 的字段;再进 PHP 源码(如果有权限)或响应 HTML 里搜 hidden 输入框,确认该 token 是否每次请求都刷新Breakpoints 功能拦截请求,在发包前手动删掉 token 字段,再放行 —— 若服务器仍执行操作,就是漏洞确认常见原因不是 ZAP 问题,而是 PHP 页面用了前端 JS 动态生成 token(比如 Vue/AJAX 初始化时从 /api/csrf-token 拿),ZAP 默认不执行 JS,所以 token 字段压根不会出现在原始 HTML 表单里。
应对方式:
Spider 时勾选 Parse JavaScript,并启用 Headless Browser(需提前装好 Chromium)History 标签页过滤 XHR 或 fetch 请求,找返回 JSON 中带 csrf_token 的接口md5(timestamp + secret)),ZAP 无法还原,必须结合 PHP 代码逻辑或 Burp 的 Extensions → CSPro 辅助session.use_only_cookies=1 配置会导致 ZAP 无法通过 URL 传 sessionid,此时必须保留 Cookie 头,否则 token 校验直接失败有些 PHP 站只校验 Referer 是否为本站,看似防 CSRF,实则极易绕过。ZAP 本身不发包爆破,但可导出请求供 curl 或 Python 复现。
典型绕过方式:
Referer: https://victim.com/admin 改成 Referer: https://victim.com.admin.evil.com(部分 PHP parse_url() 解析缺陷)Origin 头,或设为 Origin: null(某些 PHP 框架对 null 值未做严格判断)Send to Repeater 后,在 Raw 标签页手动添加换行符混淆头解析:Referer: https://victim.com\r\nX-Forwarded-Host: evil.com
$_SERVER['HTTP_ORIGIN'] 在非 CORS 请求中可能为空,此时仅靠 Referer 校验形同虚设真正难搞的是结合双重

@csrf),这种必须拿到用户 session 才能构造合法请求,ZAP 单独跑不出结果,得配合已登录态的手动重放。