先记住这个答案
TRACE 方法让服务器把收到的请求消息(请求行和所有头部)作为响应体返回,用于测试请求是否被中间设备修改。它被禁用是因为响应会反映请求头,可能包含 Cookie 或 Authorization 等敏感信息。历史上,浏览器脚本可利用 TRACE 读取回显,实现跨站跟踪攻击(XST)。出于安全考虑,许多服务器默认关闭 TRACE,返回 405 Method Not Allowed 或采用其他方式忽略。
- TRACE 回显请求用于诊断
- 禁用因防止 Cookie 泄露
- 可用 OPTIONS 或自定义头替代
TRACE 的工作机制与诊断价值
TRACE 请求由客户端(如 curl)发往目标 URL,目标服务器收到后,将请求行和所有头部作为响应体,以 Content-Type: message/http 返回,状态码 200。若中途经过代理,每个代理都可能修改请求,TRACE 让最终接收者返回收到的最终形态,从而对比原始发送与最终到达的差异,定位修改请求的节点。
这种回显本质是网络诊断工具,RFC 7231 定义其安全且幂等。客户端常通过对比响应体与原始请求,检查代理是否改写了 Host、User-Agent 等字段。当请求路径中存在 Max-Forwards 头部时,每经过一跳减一,减到 0 的服务器即返回,可用于限定诊断范围,避免多级代理时无从判断。
具体场景:检测缓存代理是否改写头部
假设我们在 Nginx 后有一层 Apache,客户端怀疑 Apache 把 Accept-Encoding 头改错。我们用 curl 发送 TRACE,命令为 curl -v -X TRACE https://api.example.com/v1/resource,同时加 Max-Forwards: 0 让 Apache 自己回显。响应体展示 Apache 实际收到的请求头列表,若发现 gzip 未被声明,就证明是前置 Nginx 剥除了该头。
但此操作若直接在生产执行,Apache 回显的数据包会包含前端可能附加的内部头,如 X-Real-IP 或认证凭证。在浏览器允许或存在漏洞的环境中,恶意网页可通过发起 TRACE 读取响应体,将内部头信息带回攻击者。因此该诊断应放在隔离的 staging 环境,且对生产服务器禁用 TRACE 并改用记录访问日志的专用调试头。
适用边界与失效条件
禁用 TRACE 并不总能消除风险。如果服务器位于反代之后,且反代自身允许 TRACE 并开启,即使源站关闭,攻击者也可直接打反代。同样,若应用将已删除的 TRACE 映射到 GET,可能意外响应 200 并返回回显,需通过严格的方法白名单校验。
另一种情况是安全要求高但保留 TRACE 用于排障。此时应只允许内网 IP 或携带特定令牌发起,并阻止浏览器 CORS 预检请求看到对 TRACE 的支持。代价是配置复杂度上升,且仍存在被利用的可能,多数组织选择全部禁用,用 OPTIONS 加 Allow 头等方式实现等价探测。
容易答错的地方
- TRACE 是安全方法所以无害
- 安全指不修改资源,但响应可能泄露请求中的敏感字段,仍可构成窃取。XST 攻击在历史上利用浏览器发起 TRACE 并读取回显,可能获得 Cookie 和 Authorization,现代浏览器已限制 TRACE 的脚本化调用。
- 启用 TRACE 能诊断所有代理问题
- 它只反映最终接收时状态,若中间设备篡改但最终节点未记录,仍难定位。且多数代理会过滤 TRACE 本身,诊断范围受限。
面试官还会怎么问?
如何安全地测试代理修改行为?
在受控测试网络使用 curl 加自定义头发 TRACE,或启用受限的回显端点,避免暴露真实 Cookie。
什么状态下 TRACE 会返回 405?
服务器实现了方法但明确拒绝,或反向代理直接拒绝。响应体通常为空,客户端可检查 Allow 头确认可用方法。
禁用 TRACE 与禁用其他方法有什么区别?
GET/HEAD 需保留,TRACE 非必要,禁用不会破坏常规服务。而禁用 DELETE 可能影响 API 语义,需权衡。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。