跳到内容

4.3 跨边界请求:CSRF、CORS 与 SSRF

CSRF 与 SSRF 都让一个有权限的组件替攻击者发送请求,但代理不同:CSRF 借用用户浏览器自动携带的凭据,SSRF 借用服务器的网络位置和服务身份。CORS 则主要控制浏览器脚本能否读取跨源响应。

CSRF 不因 SameSite 出现而消失

若应用用 Cookie 认证,浏览器可能在跨站触发的请求中自动携带它。防护应组合:

  • 状态变更只使用非安全 HTTP method;
  • SameSite=Lax/Strict 按产品流程设置;
  • 使用绑定会话的同步 token,或受控 double-submit token;
  • 校验 Origin,必要时把 Referer 作为兼容信号;
  • 高风险操作重新认证并显示交易内容;
  • 不信任同站不可信子域。

SameSite=None 场景必须配合 Secure,且需要完整 token/Origin 防护。登录 CSRF、OAuth 回调和跨站嵌入流程尤其要单独建模,不能为了让一个集成工作就全局关闭防御。

CORS 是响应读取策略

服务端通过 CORS 响应头告诉浏览器哪些 origin 的脚本可以读取响应:

http
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Credentials: true
Vary: Origin

带 credentials 时不能使用 *。动态反射 Origin 前必须与规范化后的精确 allowlist 匹配,不能用 endsWith("example.com") 接受 attackerexample.com

Preflight 不是认证机制,非浏览器客户端可直接发送请求。API 必须照常验证身份、授权、内容类型和 CSRF 条件。CORS 配错通常泄露浏览器可读数据;它并不替网络 ACL 限制谁能连接服务。

SSRF 让服务器成为网络代理

典型入口包括 URL 预览、Webhook 测试、头像抓取、PDF 渲染、云导入和“从 URL 安装插件”。攻击者可能访问:

  • loopback、私网、link-local 和云 metadata;
  • 只对内开放的管理面与数据库代理;
  • Unix socket 或非 HTTP scheme;
  • 通过重定向、DNS rebinding、IPv6/混合编码绕过的目标。

最佳防御是不要接受任意 URL:让用户选择服务端登记的 integration/object ID。若业务确实需要出站抓取,应建立专用 egress fetcher:

  1. 只允许 https 等必要 scheme;
  2. 严格解析 hostname、port、userinfo 和 IP literal;
  3. DNS 解析后拒绝 loopback、private、link-local、multicast 等地址;
  4. 建立连接时绑定已验证 IP,并检查每次重定向的新目标;
  5. 用网络策略阻断 metadata、管理网和不必要内网;
  6. 限制响应大小、类型、时间、重定向数与并发;
  7. fetcher 不携带调用方 Cookie、云凭据和内部认证头;
  8. 记录最终 IP、域名、响应大小和拒绝原因。

域名 allowlist 比任意 URL 好,但仍要处理被接管子域、DNS 变化和供应商 redirect。只用正则拒绝 127.0.0.1 会漏掉 IPv6、整数 IP 和解析后的私网地址。

Webhook 需要反向的边界控制

发送 webhook 时,目标 URL 带来 SSRF 风险;接收 webhook 时,伪造与重放成为主要风险。接收端应验证 HMAC/签名、时间戳、event ID 和规范化原始 body,并在持久化幂等键后异步处理。

不要先 JSON parse 再重新序列化验签,不同空白、字段顺序和数值表示会改变字节。错误响应也不要泄露签名比较细节。

安全响应头缩小浏览器攻击面

根据产品使用:

http
Content-Type: application/json
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()
Content-Security-Policy: frame-ancestors 'none'

HSTS 只有在确认整个域及所选子域长期支持 HTTPS、具备证书应急能力后才逐步启用;错误的长周期 includeSubDomains 会造成持久可用性事故。

边界测试矩阵

text
CSRF:跨站表单、fetch、同站恶意子域、无/错 token、异常 Origin
CORS:允许/拒绝 origin、null origin、credentials、缓存 Vary
SSRF:IPv4/IPv6 私网、redirect、DNS 变化、metadata、超大响应
Webhook:签名篡改、过期时间、重复 event、body 编码差异

下一章把应用漏洞已经拿到进程执行权作为起点,讨论操作系统怎样继续限制攻击者。

参考资料

Built with VitePress | Software Systems Atlas