什么是请求元数据
Sec-Fetch-* 是浏览器自动附加的一组请求元数据头,声明请求的发起方式(导航、子资源、脚本)与站点关系(同源、同站、跨站)。它们由浏览器设置,页面脚本无法伪造(W3C Fetch Metadata Request Headers)。
用它做什么防御
最典型的用法是给状态变更接口加一层规则:如果站点关系显示跨站,而来源又不在白名单内,就直接拒绝。这相当于在跨站请求令牌之外多一层纵深防御,对没有令牌保护的老接口尤其有价值。
基本信息
| 名称 | Sec-Fetch-Dest、Sec-Fetch-Mode、Sec-Fetch-Site、Sec-Fetch-User |
|---|---|
| 作用 | 请求上下文元数据,防跨站伪造与资源盗链 |
| 规范 | W3C Fetch Metadata Request Headers |
| 特点 | 由浏览器设置、脚本无法伪造;老浏览器可能不发送 |
典型使用场景
- 给管理接口加跨站请求拦截
- 防止图片与静态资源被外站盗链
- 排查「接口偶发被拒」:区分真实攻击与规则过严
- 与跨站请求令牌叠加做纵深防御
典型取值与验证
典型取值与验证
# 站点关系:同源 同站 跨站 或无来源(地址栏直接访问)
# Sec-Fetch-Site: same-origin | same-site | cross-site | none
# Sec-Fetch-Dest: document | script | image | empty
# 用构造请求验证规则是否符合预期
curl -s -o /dev/null -w '%{http_code}\n' -H 'Sec-Fetch-Site: cross-site' https://api.example.com/admin/action取值解读
| 头部 | 取值 | 含义 |
|---|---|---|
| Sec-Fetch-Site | same-origin | 同源发起 |
| Sec-Fetch-Site | same-site | 同站但不同源 |
| Sec-Fetch-Site | cross-site | 跨站发起 |
| Sec-Fetch-Mode | navigate | 地址栏或链接导航 |
| Sec-Fetch-Dest | empty | 脚本发起的接口调用 |
默认策略必须考虑头部缺失的情况:老浏览器、脚本客户端与第三方集成方都不会发送这些头,不能把「没有这个头」直接当恶意处理。
规则上线前先用真实流量做旁路观测:直接拒绝跨站请求会误伤正常的跨域调用与移动端内置浏览器。
和其他防御怎么配合
这组头适合做规则简单、误报可控的粗筛,用来挡住大部分明显异常的跨站写入请求;真正的授权判断仍要落在服务端:会话校验、令牌校验与来源校验谁都不能省。多层并存时,任何一层单独失效都不至于直接失守。
接口对外开放给第三方时,这种基于来源的判断基本不适用:对方大多不是浏览器,也没有这些头,规则只会不断加白名单,因此这类接口应改用密钥与签名做鉴别。