From e3f603f72a3f860da95ea984759a7f853c26598d Mon Sep 17 00:00:00 2001 From: ryan Date: Sun, 9 Aug 2026 10:42:21 +0800 Subject: [PATCH] fix(security): stop logging UptimeKuma socket payload content --- docs/changelog/index.md | 3 ++ internal/apps/openflare/uptimekuma/client.go | 38 +------------------ .../apps/openflare/uptimekuma/client_test.go | 28 -------------- 3 files changed, 4 insertions(+), 65 deletions(-) delete mode 100644 internal/apps/openflare/uptimekuma/client_test.go diff --git a/docs/changelog/index.md b/docs/changelog/index.md index aeff802a..d8f47e24 100644 --- a/docs/changelog/index.md +++ b/docs/changelog/index.md @@ -38,6 +38,9 @@ sidebar: false ### 修复 +- 修复 PoW 挑战页潜在 XSS:错误提示与状态文案改用纯文本渲染,挑战通过后的 `redir` 跳转参数仅允许 http/https 协议,防止异常文本被当作 HTML 执行或跳转到危险协议。 +- 修复邮件发送的邮件头注入风险:标题、发件人、收件人在写入邮件头前清除 CR/LF 换行符,防止注入额外邮件头(CWE-93)。 +- 修复 UptimeKuma 同步调试日志泄露凭据:Socket.IO 事件日志不再打印 payload 内容(仅记录长度),避免凭据进入日志。 - 「切换日志数据库」迁移任务修复冻结期目标库用户访问日志写入被误拦:`BuildForMigration` 未将跳过冻结标记传播到用户访问日志存储,导致迁移任务在清空目标库阶段以「log database is migrating」失败;现在目标库的清空与复制全程放行,任务可正常完成切换。 - 「切换日志数据库」迁移任务补齐第 6 张表(用户访问日志)的复制与清空;目标为 PostgreSQL 时按源库时间范围预建分区,历史日志可正常迁移;冻结前先排空批写入队列,避免在途日志丢失。 - 节点监控最新指标读取仅在 ClickHouse 为当前日志库时走 ClickHouse 快速路径,日志库切换后仪表盘不再读到旧库数据。 diff --git a/internal/apps/openflare/uptimekuma/client.go b/internal/apps/openflare/uptimekuma/client.go index 501ded5e..14f182c5 100644 --- a/internal/apps/openflare/uptimekuma/client.go +++ b/internal/apps/openflare/uptimekuma/client.go @@ -17,35 +17,6 @@ import ( "time" ) -// redactSensitiveJSON masks values of sensitive keys (password, token, secret, -// api key) so credentials never appear in logs. -func redactSensitiveJSON(v any) any { - switch t := v.(type) { - case map[string]any: - for k, val := range t { - if isSensitiveLogKey(k) { - t[k] = "***" - } else { - t[k] = redactSensitiveJSON(val) - } - } - case []any: - for i, val := range t { - t[i] = redactSensitiveJSON(val) - } - } - return v -} - -func isSensitiveLogKey(k string) bool { - switch strings.ToLower(k) { - case "password", "passwd", "secret", "token", "access_token", "api_key", "apikey": - return true - default: - return false - } -} - const emitAckTimeout = 10 * time.Second // Monitor represents a monitor entry from Uptime Kuma. @@ -321,14 +292,7 @@ func (c *SocketIOClient) Emit(event string, args ...any) (string, error) { } body := fmt.Sprintf("42%d%s", id, string(bs)) - logPayload := string(bs) - var decoded any - if err := json.Unmarshal(bs, &decoded); err == nil { - if redacted, err := json.Marshal(redactSensitiveJSON(decoded)); err == nil { - logPayload = string(redacted) - } - } - slog.Debug("Emitting Socket.IO event", "event", event, "ackID", id, "payload", logPayload) + slog.Debug("Emitting Socket.IO event", "event", event, "ackID", id, "payload_len", len(bs)) u := fmt.Sprintf("%s/socket.io/?EIO=4&transport=polling&sid=%s", c.baseURL, c.sid) req, err := http.NewRequestWithContext(c.ctx, http.MethodPost, u, strings.NewReader(body)) diff --git a/internal/apps/openflare/uptimekuma/client_test.go b/internal/apps/openflare/uptimekuma/client_test.go deleted file mode 100644 index 5aa2a2fd..00000000 --- a/internal/apps/openflare/uptimekuma/client_test.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2026 Arctel.net -// SPDX-License-Identifier: Apache-2.0 - -package uptimekuma - -import ( - "encoding/json" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestRedactSensitiveJSON(t *testing.T) { - payload := []byte(`["login",{"username":"admin","password":"s3cret","nested":{"token":"abc","label":"keep"}},"plain"]`) - var decoded any - require.NoError(t, json.Unmarshal(payload, &decoded)) - out, err := json.Marshal(redactSensitiveJSON(decoded)) - require.NoError(t, err) - - s := string(out) - assert.NotContains(t, s, "s3cret") - assert.NotContains(t, s, "abc") - assert.Contains(t, s, `"password":"***"`) - assert.Contains(t, s, `"token":"***"`) - assert.Contains(t, s, `"label":"keep"`) - assert.Contains(t, s, `"username":"admin"`) -}