fix(channel): 渠道适配器与出站工具的上游响应体/带凭据 URL 不再进日志与错误(M41)
接 M38 的 18 条真泄漏里「渠道适配器 + 出站工具」这一族(#10 #11 #12 #13 #15 #16)。 只动日志与 error 文字:发送/接收、解析口径、重试次数一个都没改。 - httpclient.do:非 2xx 不再把 512B 响应体原文拼进 error,改 trace.UpstreamError (状态/体积/sha256 前缀)+ 信封 code/message(RedactText + 200 rune);error 里的 target 改 trace.HostOf,并剥掉 *url.Error 外壳(它带整条地址) - telegram doJSON:4xx 只解 error_code/description(清洗 + 截断),体其余字段不拼; 传输错误只留来源 —— Bot API 把 token 写在地址路径里 - weixin_ilink doJSON:4096B 体 ⇒ trace.UpstreamError,rawURL ⇒ mediafetch.HostOf; uploadOnce 剥掉预签名上传地址(encrypted_query_param),重试日志补来源主机 - qq_obv11 connectClient 成功 INFO:改走同包已有的 maskAccessTokenQuery (OneBot 惯例把 ?access_token= 写进 remote_url) - plugins/tools/io http 拦截日志:改记 trace.HostOf + 原因码,不记原 URL、也不记错误 原文(解析失败时它包着 *url.Error) 每条都有能变异打红的用例:QQ/iLink 预签名地址的哨兵、三处 4xx 体哨兵、 user:pass@ 与 query 凭据;八处变异逐条验证变红。
This commit is contained in:
1 parent
46a6da13e0
commit
0f9251b983
11 files changed
+726
-29
No files matched your search
@@ -2,6 +2,7 @@ package io
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
stdio "io"
|
||||
"log/slog"
|
||||
@@ -10,6 +11,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.yeij.top/AskaEth/Cyrene_v2/internal/runtime/trace"
|
||||
"git.yeij.top/AskaEth/Cyrene_v2/pkg/plugins/sdk"
|
||||
)
|
||||
|
||||
@@ -58,6 +60,18 @@ func (h *httpTool) Parameters() (map[string]any, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
// blockReason 把一次拦截归类成稳定原因码,供审计日志使用。日志只记这个码与来源主机:
|
||||
// 拦截原因的具体文本(哪个 scheme、解析失败原话)会经错误返回给调用方,而错误文本本身
|
||||
// 可能带着原 URL —— 那是**不进日志**的那一侧。
|
||||
func blockReason(err error) string {
|
||||
switch {
|
||||
case errors.Is(err, ErrSSRF):
|
||||
return "ssrf_blocked"
|
||||
default:
|
||||
return "url_rejected"
|
||||
}
|
||||
}
|
||||
|
||||
// Execute implements sdk.Tool.
|
||||
func (h *httpTool) Execute(ctx context.Context, args any) (any, error) {
|
||||
m, ok := args.(map[string]any)
|
||||
@@ -77,7 +91,11 @@ func (h *httpTool) Execute(ctx context.Context, args any) (any, error) {
|
||||
}
|
||||
u, err := validateRequestURL(ctx, rawURL, h.allowedHosts)
|
||||
if err != nil {
|
||||
h.log.Warn("io http: blocked request", "url", rawURL, "err", err)
|
||||
// 只记来源与原因码:rawURL 由模型/用户给,可能带 user:pass@ 或 ?api_key=,
|
||||
// 而日志会被采集与转贴;错误原文也不进日志 —— 解析失败时它包着 *url.Error,
|
||||
// 里面就是整条原串。
|
||||
h.log.Warn("io http: blocked request",
|
||||
"host", trace.HostOf(rawURL), "reason", blockReason(err))
|
||||
return nil, err
|
||||
}
|
||||
body := argString(m, "body")
|
||||
|
||||
Reference in new issue
Block a user