Skip to content

[Privacy] Sanitize credentials in persisted connection endpoints (connections.json stores userinfo in cleartext) #93

Description

@yjg-djb

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。它当前不构成出站泄露,但存在两个风险:

  1. 用户在 Settings UI 里可见/可复制完整凭证(connection health 回显链路);
  2. 未来任何同步/导出/诊断增强若包含该文件,凭证将随之一并离开设备——与 [Privacy] Centralize redaction and data minimization for logs, diagnostics, traces, and eval artifacts #19 建立的“在统一边界前脱敏”精神不一致。

Requirements

  • ConnectionStore.setConfig 持久化前对 endpoint 做 secret 形态剥离:URL userinfo 中的密码部分以 [REDACTED] 或等价标记替代(或整个 userinfo 移除),主机/协议/路径保留,保证功能语义(可读的目标地址)不丢;
  • 读取侧(回显到 UI/health 消息)同样不出现明文 userinfo;
  • 对已存在的旧文件:读取时惰性净化(next write 落盘净化版本),或一次性迁移;
  • [Privacy] Centralize redaction and data minimization for logs, diagnostics, traces, and eval artifacts #19redactText 规则源对齐(URL userinfo 模式已存在),不新造正则;
  • 不改变非 secret endpoint(无 userinfo)的存储行为。

Acceptance Criteria

  • setConfig 写入带 userinfo 的 endpoint 后,connections.json 中不含明文密码;
  • getConfig / connection health 回显不含明文 userinfo;
  • 既有无 userinfo endpoint 的行为与测试保持不变;
  • 单测覆盖:userinfo 密码、userinfo 仅用户名、无 userinfo、query 中 token 等形态。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

claimedClaimed by a contributor and currently in progress

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions