Background
Folio 的连接配置把 endpoint 原样明文落盘到 connections.json(userData 目录)。ProviderConfig 的接口注释写明 "Non-secret provider settings. Credentials belong in the OS-backed CredentialStore",ConnectionStore.setConfig 也刻意做了字段白名单(不落 apiKey),但 endpoint 字段本身没有做任何 secret 形态检查 ——而 URL userinfo(https://user:password@host)恰恰是一种常见凭证携带形态(连接串风格)。
实测证据(production path)
在真实应用中经 connections.setConfig IPC 写入:
endpoint: 'https://folio_user:CANARYLEAK04dbpass@db.host.internal/api'
落盘的 connections.json(userData):
"configs" : { "massive" : { "enabled" : true ,
"endpoint" : " https://folio_user:CANARYLEAK04dbpass@db.host.internal/api" } }
该发现出现在 PR #64 的 production canary 运行中(详见该 PR 的证据评论):所有 outbound 产物(diagnostics bundle、eval artifacts、IPC 错误)均 0 canary——统一脱敏层工作正常——但这个 at-rest 本地文件按本地优先设计原样保存了 userinfo。它当前不构成出站泄露,但存在两个风险:
用户在 Settings UI 里可见/可复制完整凭证 (connection health 回显链路);
未来任何同步/导出/诊断增强 若包含该文件,凭证将随之一并离开设备——与 [Privacy] Centralize redaction and data minimization for logs, diagnostics, traces, and eval artifacts #19 建立的“在统一边界前脱敏”精神不一致。
Requirements
Acceptance Criteria
Background
Folio 的连接配置把 endpoint 原样明文落盘到
connections.json(userData 目录)。ProviderConfig的接口注释写明 "Non-secret provider settings. Credentials belong in the OS-backed CredentialStore",ConnectionStore.setConfig也刻意做了字段白名单(不落 apiKey),但 endpoint 字段本身没有做任何 secret 形态检查——而 URL userinfo(https://user:password@host)恰恰是一种常见凭证携带形态(连接串风格)。实测证据(production path)
在真实应用中经
connections.setConfigIPC 写入:endpoint: 'https://folio_user:CANARYLEAK04dbpass@db.host.internal/api'落盘的
connections.json(userData):该发现出现在 PR #64 的 production canary 运行中(详见该 PR 的证据评论):所有 outbound 产物(diagnostics bundle、eval artifacts、IPC 错误)均 0 canary——统一脱敏层工作正常——但这个 at-rest 本地文件按本地优先设计原样保存了 userinfo。它当前不构成出站泄露,但存在两个风险:
Requirements
ConnectionStore.setConfig持久化前对endpoint做 secret 形态剥离:URL userinfo 中的密码部分以[REDACTED]或等价标记替代(或整个 userinfo 移除),主机/协议/路径保留,保证功能语义(可读的目标地址)不丢;redactText规则源对齐(URL userinfo 模式已存在),不新造正则;Acceptance Criteria
setConfig写入带 userinfo 的 endpoint 后,connections.json中不含明文密码;getConfig/ connection health 回显不含明文 userinfo;