五处逐字同形的三行(mediafetch.sanitizeErr / httpclient.transportCause / vision.fetchCause / telegram.callCause / weixin_ilink.urlFreeCause)收敛为 trace 包里的唯一实现,13 个调用点改为直接调用;5 份 body 只剩 1 份,5 个 未导出符号与其文件内注释整份删除(不留薄封装)。 行为等价:只剥 *url.Error、不新增包装,内层哨兵链(context 取消/超时、 *net.DNSError 等)原样透传,因此重试/降级/熔断的分类判据不变。两处刻意的 收紧: - 逐层剥:内层若还是 *url.Error 也一起剥(只剥一层时内层仍带同一段地址); - *url.Error 的 Err 为 nil(或链自引用)时不再回落到原串,退化成只含 Op 的 替身 —— 那种错误无法在不带地址的前提下原样返回,而地址里就是凭据。 顺带把 httpclient 的 user:pass@ 用例改成变异可打红:net/http 自己在 *url.Error 里就把密码打成 ***,「密码不出现」在剥壳与不剥壳下都成立(空跑), 用户名才是分水岭。 验收:go build ./... + go vet ./... + 指定包 go test -count=1 全绿; 变异验证(把 URLCause 改成透传)⇒ 五处「不含 URL」断言全红。
- SSRF 三层:① 字面主机判定(**链路本地** `169.254.0.0/16`/`fe80::/10`(先 Unmap ⇒ `::ffff:169.254.169.254` 绕不过)+ 云元数据 `100.100.100.200`、`fd00:ec2::/64`);② 重定向逐跳校验 + 上限 5 跳; ③ **建连前校验解析结果并用校验过的 IP 直连**(防 DNS 重绑,拨号器不再二次解析) - **没打断同源自取**(两条独立证据):`127.0.0.1:<port>/api/v1/files/<32hex>.png` 端到端取回成功、 私网地址**原样交给底层拨号器**;被拒地址则底层拨号器 0 次调用(无真实连接发出) - 失败文案**不含 URL/查询串签名**;非图片响应仍 `ErrNotImage` 且不泄漏响应体 - base64 路径长度预检(**先于 DecodeString 与 `data:` 短路**,零分配):口径与网关同值同推导 (`((5MiB+2)/3)*4+64`),超限 `ErrImageTooLarge`、文案只含上限与本次长度 - 复核:vision 包 build/vet/测试绿(15 条新用例);**4 条变异反证**(守卫整体短路 → 8 条被拒地址全中; 只短路链路本地分支 → 4 红且实测「无守卫时进程真的去连 169.254.169.254」;预检恒 nil → 3 红; 去掉重定向校验仍全绿 ⇒ 证明第三层独立兜住) - 登记:`CHAT_IMAGE_MAX_BYTES` 调大 > 默认时「网关照放、vision 拒」的配置耦合(待单一真源对齐)