footprintai/containarium 是一个开源智能体运行时,具备原生 SSH 隔离、eBPF 出站策略、Kubernetes 与 LXC 后端、GPU 直通以及原生 MCP CLI。2026-11-03 的提交 4be7f81(#3455, #3468) 将该运行时 internal/server 日志中租户提供的字符串从 %s 改为用 %q 引用。
背景是日志伪造与终端控制。像用户名或容器名这类由租户决定的值,如果带有换行字符,就可以伪造出一整行日志;ESC 字符则可能原样传递到运维人员的终端。本次变更覆盖用户名、box 与容器名、tracker 连接名与项目名、卷与密钥名称、进程名、run id 和 token id,并一并修复了 internal/server 中的 346 处 log.Printf 以及 run-checkout sweep 中的 4 个注入式 logger。配置路径、IP、持续时间、peer id、枚举状态、服务器生成的 id 等运维/守护进程侧的值则保持原样。
验证也一并加入。503 行的 log_quote_test.go 会在每一类值对应的处理器中注入换行和 \x1b,检查日志中不残留控制字节和伪造的行;同时遍历包 AST,一旦再次出现将租户值表达式绑定到 %s 或 %v 的 log.Printf 就让测试失败。评审后的后续提交把这项检查扩展到 log.Print、Println、Fatal、Panic 以及注入的 printf logger,并引用了令牌轮换行的 jti 与 family id 以及 checkout sweep 名称。用户删除失败日志中不再把名字追加到 'sudo userdel -r' 提示上,也是同一系列的清理,因为 Go 的 %q 并不是 shell 引号。
局限显然仍然存在。正如 changelog fragment 所写明,附加在日志行之后的错误文本仍未用 %v 引用,因此错误中夹带的值依然可能破坏一行日志,该问题正在单独跟踪。如果现有日志过滤器依赖 user=alice 这样的旧格式,就需要更新。取值现在呈现为 user="alice" 形式,sweep 行呈现为 [run-checkout-sweep] "<name>-container": 形式,从 box 捕获的 stderr 则像 stderr="line one\nline two" 一样保留为一行。这是一项阻止用租户值污染日志的防御性修改,并且附带验证,但错误路径上残留的部分与过滤器迁移仍需运维人员自行承担。