Photo by Unsplash
802 字
4 分钟
格式化请求头,排除敏感信息
格式化请求头,排除敏感信息
调试 API 或者寻求帮助时,经常需要分享请求头信息。但直接复制粘贴可能会泄露敏感数据,比如 Token、IP 地址等。这篇笔记记录一下清理方法。
原始请求头示例
从某个 API 调用中抓到的请求头:
Content-Type: application/jsonAccept: */*Content-Length: 2469Cf-Visitor: {"scheme":"https"}Accept-Encoding: gzip, brCf-Ray: 9daf35915b4133cf-NRTCdn-Loop: cloudflare; loops=1Connection: Keep-AliveCf-Ipcountry: JPX-Forwarded-Proto: httpsUser-Agent: opencode/1.2.24 ai-sdk/provider-utils/3.0.20 runtime/bun/1.3.10Cf-Connecting-Ip: 212.107.30.202X-Forwarded-For: 212.107.30.202Authorization: Bearer sk-h...code这里面有些东西不该公开:
Authorization- 包含 API TokenCf-Connecting-Ip/X-Forwarded-For- 真实 IP 地址Cf-Ray/Cdn-Loop/Cf-Visitor- Cloudflare 的追踪信息Content-Length- 随请求体变化,不是固定值
清理后的版本
保留必要的标准头字段:
headers: Content-Type: application/json Accept: "*/*" Accept-Encoding: "gzip, br" User-Agent: "opencode/1.2.24 ai-sdk/provider-utils/3.0.20 runtime/bun/1.3.10"各类请求头字段说明
应该保留的标准字段
| 字段名 | 说明 | 示例 |
|---|---|---|
| Content-Type | 请求体格式 | application/json |
| Accept | 可接受的响应格式 | */* 或 application/json |
| Accept-Encoding | 支持的压缩格式 | gzip, br |
| User-Agent | 客户端标识 | curl/7.68.0 |
| Content-Length | 请求体长度(可选) | 2469 |
这些字段通常不包含敏感信息,对调试有帮助。
应该移除的敏感字段
| 字段名 | 说明 | 风险 |
|---|---|---|
| Authorization | 认证信息 | 泄露 Token |
| Cookie | 会话凭证 | 可能被劫持 |
| X-Api-Key | API 密钥 | 直接泄露密钥 |
| X-Auth-Token | 认证令牌 | 会话被盗用 |
| Proxy-Authorization | 代理认证 | 代理凭证泄露 |
通常可以移除的临时/追踪字段
| 字段名 | 说明 |
|---|---|
| X-Forwarded-For | 原始客户端 IP |
| X-Real-Ip | 真实 IP |
| Cf-Connecting-Ip | Cloudflare 传递的 IP |
| X-Request-Id | 请求追踪 ID |
| Trace-Id | 链路追踪 ID |
| X-Amzn-Trace-Id | AWS 追踪 ID |
这些字段通常由 CDN、负载均衡或网关自动添加,对问题诊断帮助不大,反而可能暴露部署信息。
自动清理脚本
用 Python 快速清理:
import re
# 定义要移除的敏感字段模式SENSITIVE_PATTERNS = [ r'^Authorization:.*$', r'^Cookie:.*$', r'^X-Api-Key:.*$', r'^X-Auth-Token:.*$', r'^X-Forwarded-For:.*$', r'^X-Real-Ip:.*$', r'^Cf-Connecting-Ip:.*$', r'^Cf-Ray:.*$', r'^Cdn-Loop:.*$', r'^Cf-Visitor:.*$', r'^Cf-Ipcountry:.*$', r'^Content-Length:.*$', r'^Connection:.*$',]
def clean_headers(headers_text): lines = headers_text.strip().split('\n') cleaned = []
for line in lines: should_keep = True for pattern in SENSITIVE_PATTERNS: if re.match(pattern, line, re.IGNORECASE): should_keep = False break if should_keep: cleaned.append(line)
return '\n'.join(cleaned)
# 使用示例raw_headers = """Content-Type: application/jsonAuthorization: Bearer sk-xxxxxxxxX-Forwarded-For: 192.168.1.1User-Agent: MyApp/1.0"""
print(clean_headers(raw_headers))使用 jq 处理 JSON 格式的头信息
如果请求头是以 JSON 格式存储的:
{ "Content-Type": "application/json", "Authorization": "Bearer sk-xxx", "X-Forwarded-For": "192.168.1.1", "User-Agent": "MyApp/1.0"}用 jq 删除敏感字段:
# 删除特定字段jq 'del(.Authorization, .["X-Forwarded-For"], .Cookie)' headers.json
# 只保留白名单字段jq '{"Content-Type", "Accept", "User-Agent", "Accept-Encoding"}' headers.json格式化 YAML 配置
在配置文件中使用清理后的请求头:
api_client: base_url: https://api.example.com timeout: 30 headers: Content-Type: application/json Accept: application/json User-Agent: "MyBot/1.0" # 注意:Authorization 通过环境变量注入,不写在配置里对应的代码读取方式:
import osimport yaml
with open('config.yaml') as f: config = yaml.safe_load(f)
headers = config['api_client']['headers']headers['Authorization'] = f"Bearer {os.environ['API_KEY']}"检查清单
分享请求头前确认:
- 没有 Authorization 头或已脱敏
- 没有 Cookie 头
- 没有 X-Forwarded-For 等 IP 相关头
- API Key 没有直接写在头里
- 不是生产环境的真实凭证
如果不确定某个字段是否敏感,保守的做法是删掉它。
小结
分享调试信息时,宁可少给一点,也别泄露敏感数据。养成清理请求头的习惯,既能保护隐私,也不会让帮忙看问题的人被无关信息干扰。