fix: VUL-005 修复日志注入(RequestURI 与上游错误体转义)

VUL-005 (低): 攻击者可在 HTTP 请求 URL 或上游错误响应中
注入 \n / \r 字符,伪造日志行干扰排障。无代码执行风险。

修复位置:
  - middleware/logger.go: 访问日志中的 r.RequestURI 是未经
    解析的原始请求行,客户端可控。转义 \n / \r 为字面字符
  - adapter/volcano/synthesis.go: 上游非 200 响应体 (rawBody)
    可能是攻击者控制的恶意内容,转义后再嵌入错误消息
This commit is contained in:
sun
2026-08-26 11:52:28 +08:00
parent a238e5c2a4
commit 91b0c8acee
2 changed files with 10 additions and 2 deletions
+5 -1
View File
@@ -6,6 +6,7 @@ import (
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"log" "log"
"strings"
"time" "time"
"github.com/volcano-tts/tts-api/common" "github.com/volcano-tts/tts-api/common"
@@ -94,10 +95,13 @@ func Synthesis(
if resp.StatusCode != 200 { if resp.StatusCode != 200 {
rawBody := ReadErrorBody(resp.Body) 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) 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{ return nil, &UpstreamError{
Code: resp.StatusCode, 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", Stage: "http",
} }
} }
+5 -1
View File
@@ -3,6 +3,7 @@ package middleware
import ( import (
"log" "log"
"net/http" "net/http"
"strings"
"time" "time"
) )
@@ -23,6 +24,9 @@ func Logger(next http.Handler) http.Handler {
next.ServeHTTP(rec, r) next.ServeHTTP(rec, r)
duration := time.Since(start) 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)
}) })
} }