mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-09-29 05:56:38 +08:00
fix(security): stop logging UptimeKuma socket payload content
This commit is contained in:
@@ -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 快速路径,日志库切换后仪表盘不再读到旧库数据。
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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"`)
|
||||
}
|
||||
Reference in New Issue
Block a user