Skip to content

根治 HTTP 响应头自由文本注入(raw 导出 502 事故) - #210

Merged
zj1123581321 merged 4 commits into
mainfrom
card/VideoTranscriptAPI-261009-fix
Oct 9, 2026
Merged

zj1123581321 merged 4 commits into
mainfrom
card/VideoTranscriptAPI-261009-fix

Conversation

@zj1123581321

Copy link
Copy Markdown
Collaborator

根治 HTTP 响应头自由文本注入(502 事故修复)

现象与根因

GET /view/<token>?raw=calibrated 经 Cloudflare 返回 502(error code: 502,cloudflared 隧道报错),无 query 的页面正常。n305 源站直打复现 Empty reply from server;uvicorn 日志为 h11._util.LocalProtocolError: Illegal header value b"here's how i shipped 2,500 PRs...\n\n..."。

根因:_safe_header_value() 只处理字符集维度(非 ASCII → quote()),纯 ASCII 值中的 \r\n\t 与首尾空白原样进入 X-Document-Title 等响应头;h11 在响应发送阶段拒绝,连接复位。此时 handler 已记 200,边缘只见 502,无本侧告警(命中 risk-tier personal 档 P1「静默出错」)。

修法(输出端上下文编码,双顾问会诊定稿)

  • _safe_header_value() 重写:值完全为可打印 ASCII(\x20-\x7E)、首尾非空格/Tab、不含 % 时原样输出;否则整体 UTF-8 百分号编码;编码后上限 512 字节,按字符边界截断、剥尾随空白(二分搜索最大前缀)
  • _build_text_metadata_header() Title 行折叠 \r\n\t 为单空格(同一 title 同一请求,raw 导出面向外部 AI fetcher,front matter 必须同卡修)
  • 三处导出日志 view_token 打真实值前 20 位(原来恒 unknown,取证误导)
  • docs/guides/api/quickstart.md 元数据头描述与实现对齐(原「RFC 5987」表述与裸 quote() 实现不符)

锁定决策(双顾问会诊 vta-header-inject-rootfix-261009)

  1. 就地修编码器,不迁 utils/(三入口已共用 _build_metadata_headers,无第二消费者证据)
  2. 不加 ASGI 兜底中间件(异常抛在 ASGI 边界外属上报链路问题,另立 issue;编码器+h11 契约测试已从源头堵类)
  3. 不洗存量 DB(HTML 展示依赖原始 title)
  4. 三个 X- 头保留(ebd27a82 有意添加,消费方为外部 AI fetcher)
  5. h11 判定器而非裸 ASGITransport(后者不过 h11 校验,测不到本缺陷——codex 实证)
  6. 存量数据零迁移

验证证据

  • 契约测试 tests/unit/test_header_value_encoding.py:9 组对抗样本 × 三入口真调用,h11.Response 构造判定 + 512 上限 + 行纪律断言;独立红验抽查:仅还原 _safe_header_value 旧实现,test_three_entrypoints_contract[line1\n\nline2](生产同款样本)等以 LocalProtocolError 精准转红
  • 窄验 32 passed(1.97s);make test 全量退出码 0(100% 到顶)
  • OCR 前置扫描 reviewed_fallback,0 findings
  • 运行镜像 699689b8 与 HEAD 在缺陷函数区间零差异,根因对线上成立

风险与后续

  • 上线后需边缘验证:用户报障 URL 过 Cloudflare 应 200 且响应头可解析(部署后执行)
  • 另立 issue:① GlitchTip 收不到 ASGI app 之外的发送阶段异常;② 企微通知 markdown 转义(P3)

Refs: 会诊任务 vta-header-inject-rootfix-261009(codex=降级→条件全吸收,opus=继续)

zj1123581321 added 3 commits October 9, 2026 16:59
Agent-Executor: agy
Agent-Model: gemini-3.8-flash-high
Agent-Effort: unknown
Dispatch-Id: dlg-20261009-084646-4733c7
Task-Id: VideoTranscriptAPI-20261009-19
Agent-Executor: agy
Agent-Model: gemini-3.8-flash-high
Agent-Effort: unknown
Dispatch-Id: dlg-20261009-084646-4733c7
Task-Id: VideoTranscriptAPI-20261009-19
Agent-Executor: agy
Agent-Model: gemini-3.8-flash-high
Agent-Effort: unknown
Dispatch-Id: dlg-20261009-084646-4733c7
Task-Id: VideoTranscriptAPI-20261009-19
@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Required Gate v2 — 状态面板

当前状态:pass · 可合并

当前裁决:code_pass / primary_pass

PR 累计主审轮(影子):2/5 · collecting

Gate 历史(v1;来源为持久化 gate_terminal 制品)

Run Attempt Head 状态 PR 累计主审轮(影子) 收件人动作
37913280328 1 c940542 fail — 要修代码
37913280328 2 c940542 fail — 要修代码
37921290277 1 cb3c2e0 pass 2/5 · collecting 可合并

历史行按 run_id + run_attempt 去重并只增不删;删除本评论后可由 gate_terminal 制品重建。

zj1123581321 added a commit that referenced this pull request Oct 9, 2026
…robe

容量探针就绪等待由 sleep 改为轮询(解开 #210 quality 红)
@zj1123581321
zj1123581321 merged commit bd7510a into main Oct 9, 2026
13 checks passed
@zj1123581321
zj1123581321 deleted the card/VideoTranscriptAPI-261009-fix branch October 9, 2026 11:15
zj1123581321 added a commit that referenced this pull request Oct 15, 2026
…robe

容量探针就绪等待由 sleep 改为轮询(解开 #210 quality 红)
zj1123581321 added a commit that referenced this pull request Oct 15, 2026
根治 HTTP 响应头自由文本注入(raw 导出 502 事故)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant