Files
HomeAgent/internal/agent/core/log_scrub.go
JianFeeeee 4e70b8d5d8 refactor(module): 核心仓 Go module 路径改为 github.com/JianFeeeee/HologramAgent
批 1,不含 SDK 仓与目录改名。

- go.mod 第 1 行 module 路径
- 366 个 .go 文件的完整前缀 github.com/JianFeeeee/HomeAgent 机械替换
  (857 处,仅完整前缀;展示名/注释里的 HomeAgent 字样留给批 5)
- 未改:third_party 目录名、SDK 自身 go.mod module、go.mod replace 目标、
  homed/waiter 可执行名、.hmap 后缀
2026-10-21 12:17:19 +08:00

61 lines
2.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package core
// 日志脱敏:写进日志的文本必须先清洗明文凭据。
//
// ## 为什么这条比"拦住模型"更紧迫
//
// 模型上下文是**短期**的:一轮对话结束就不再发送。
// 而日志是**长期**的:
//
// /home/newqqagent/log/homed_*.log 每天一个文件,从不自动清理
// systemd journal 另存一份
// 用户/技术支持/issue 排查时会把日志贴出来
//
// 一次泄漏进日志 = 永久泄漏。凭据被轮换前,任何拿到日志的人都能用。
//
// ## 具体泄漏点(2026-10-18 审计)
//
// task.go:1031 log.Printf("[agent] tool %s result: %s", ..., truncateStr(result, 100))
// ← 工具输出可能含服务端回显的凭据(enc_shell 跑 curl 拿 200)
// task.go:967 log.Printf("[agent] tool %s raw_arguments: %s", ..., truncateStr(tc.RawArguments, 300))
// ← 模型给的原始参数。正常是别名,但插件工具可能被直接传明文
//
// 两处都**原样打印**,没有经过 security.Replace。
//
// ## 实现
//
// scrubForLog 是唯一入口,所有"把工具内容写进日志"的地方都走它。
// 空安全:security.Global() 未初始化时原样返回(不 panic、不阻塞)。
// 幂等:已是别名(sec_xxx)的文本再扫一次不会被改动。
import (
"log"
"github.com/JianFeeeee/HologramAgent/internal/security"
)
// scrubForLog 清洗要写进日志的文本。
//
// where 用于日志里标注拦截位置(如 "tool_result:enc_shell"),
// 便于事后审计"哪些工具的输出带凭据"。
func scrubForLog(text, where string) string {
if text == "" {
return text
}
st := security.Global()
if st == nil {
return text
}
out, evts := st.Replace(text, "log:"+where, security.Patterns)
if len(evts) == 0 {
return text
}
// 拦截本身要记一笔(不打印原文,只打印模式与长度)——
// 否则运维不知道"这个工具经常吐凭据",也就不会去修插件。
for _, e := range evts {
log.Printf("[security] 日志拦截 %s ← %s(%d 字节),原文未落盘",
where, e.Kind, e.Len)
}
return out
}