From 91b0c8acee16978e47910711c8120e6d636a4c73 Mon Sep 17 00:00:00 2001 From: "3371392206@qq.com" <3371392206@qq.com> Date: Wed, 26 Aug 2026 11:52:28 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20VUL-005=20=E4=BF=AE=E5=A4=8D=E6=97=A5?= =?UTF-8?q?=E5=BF=97=E6=B3=A8=E5=85=A5(RequestURI=20=E4=B8=8E=E4=B8=8A?= =?UTF-8?q?=E6=B8=B8=E9=94=99=E8=AF=AF=E4=BD=93=E8=BD=AC=E4=B9=89)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit VUL-005 (低): 攻击者可在 HTTP 请求 URL 或上游错误响应中 注入 \n / \r 字符,伪造日志行干扰排障。无代码执行风险。 修复位置: - middleware/logger.go: 访问日志中的 r.RequestURI 是未经 解析的原始请求行,客户端可控。转义 \n / \r 为字面字符 - adapter/volcano/synthesis.go: 上游非 200 响应体 (rawBody) 可能是攻击者控制的恶意内容,转义后再嵌入错误消息 --- adapter/volcano/synthesis.go | 6 +++++- middleware/logger.go | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/adapter/volcano/synthesis.go b/adapter/volcano/synthesis.go index 5a461da..0c90237 100644 --- a/adapter/volcano/synthesis.go +++ b/adapter/volcano/synthesis.go @@ -6,6 +6,7 @@ import ( "encoding/hex" "fmt" "log" + "strings" "time" "github.com/volcano-tts/tts-api/common" @@ -94,10 +95,13 @@ func Synthesis( if resp.StatusCode != 200 { rawBody := ReadErrorBody(resp.Body) + // rawBody 来自上游响应体,可能是攻击者控制的恶意内容(例如包含 + // \n 伪造日志行)。转义后再嵌入错误消息。 + safeBody := strings.NewReplacer("\n", "\\n", "\r", "\\r").Replace(rawBody) mtr.UpstreamFinished(opts.Speaker, opts.Model, opts.Format, fmt.Sprintf("http_%d", resp.StatusCode), time.Since(started), 0, 0, 0, resp.StatusCode) return nil, &UpstreamError{ Code: resp.StatusCode, - Message: fmt.Sprintf("upstream http %d: %s", resp.StatusCode, rawBody), + Message: fmt.Sprintf("upstream http %d: %s", resp.StatusCode, safeBody), Stage: "http", } } diff --git a/middleware/logger.go b/middleware/logger.go index ea53db2..7863b3c 100644 --- a/middleware/logger.go +++ b/middleware/logger.go @@ -3,6 +3,7 @@ package middleware import ( "log" "net/http" + "strings" "time" ) @@ -23,6 +24,9 @@ func Logger(next http.Handler) http.Handler { next.ServeHTTP(rec, r) duration := time.Since(start) - log.Printf("%s %s %s %d %v", r.Method, r.RequestURI, r.RemoteAddr, rec.statusCode, duration) + // r.RequestURI 是未经解析的原始请求行,攻击者可在 URL 中注入 + // \n / \r 伪造日志行。转义为可见字符后再记录。 + uri := strings.NewReplacer("\n", "\\n", "\r", "\\r").Replace(r.RequestURI) + log.Printf("%s %s %s %d %v", r.Method, uri, r.RemoteAddr, rec.statusCode, duration) }) }