审计自家Claude日志后发现真实凭证泄露

Claude Code把所有读到的凭证都明文写进了本地JSONL文件

一位开发者在检查自己Mac上的Claude Code日志时,发现了真实可用的API密钥、数据库连接字符串和环境变量输出。这些信息并非来自外部攻击,而是AI编码代理正常工作时主动读取并记录下来的。Claude Code会读取.env文件、执行cat命令、运行shell指令,所有动作都被逐字写入~/.claude/projects/**/*.jsonl文件,用于支持会话恢复。这意味着任何它“看到”过的凭证都会永久以明文形式留在磁盘上。

这个发现并非孤例。AI编码工具在本地运行时,设计上需要完整上下文才能继续对话,因此把用户终端输出、文件内容全部存档成了默认行为。开发者此前几乎没人去检查这些日志文件,导致潜在泄露长期存在。

AI编码代理如何一步步把凭证写进日志

Claude Code这类工具的工作流程是:用户要求它帮忙调试或生成代码,它就会主动读取项目文件、运行shell命令来获取环境信息。例如,当开发者说“帮我看下数据库连接为什么失败”,代理可能直接执行cat .envenv命令。这些命令的输出被完整捕获并写入会话记录,以便下次继续对话时保持上下文。

日志文件采用JSONL格式,每一行都是一条完整的交互记录。里面不仅有用户输入和AI回复,还包含所有工具调用结果,包括文件内容和命令输出。开发者在审计时发现,自己的AWS密钥、Stripe密钥、PostgreSQL连接URL都原样保存在多个历史会话文件中。这些文件没有加密,也没有自动清理机制。

更麻烦的是,Claude Code的日志目录结构按项目组织,每个项目都有独立的JSONL文件。只要项目还在,日志就一直存在。即使开发者已经删除.env文件,历史记录里仍然留有完整副本。

真实审计结果:不止一个密钥泄露

审计者编写了一个小型CLI工具,专门扫描Claude的日志目录,提取所有看起来像凭证的字符串。结果在他自己的机器上找到了多个有效凭证:一个是生产环境的API密钥,另一个是数据库URL,其中包含用户名和密码。还有几次env命令的完整输出,把所有环境变量都暴露了出来。

这些凭证并非测试用的假数据,而是真实可用于访问外部服务的密钥。审计者确认其中至少两个密钥在日志中存活了数周。如果机器被窃取、或日志被意外上传到代码仓库,这些凭证就会立刻成为攻击目标。

这个案例说明,问题不在于AI模型本身是否安全,而是本地代理与用户文件系统深度集成带来的副作用。代理为了提供更好帮助,主动去读敏感文件,却没有同步考虑记录后的安全处置。

日志文件成为新的凭证存储库

传统上,开发者会把凭证放在.env文件里,并确保这个文件被加入.gitignore。但AI编码代理打破了这个假设。它主动读取这些被忽略的文件,并把内容复制到另一个开发者通常不会检查的位置。

.claude目录默认不被版本控制,但它仍然是本地磁盘上的明文文件。任何能访问开发者电脑的人、任何恶意软件、甚至云备份服务,都可能读取到这些日志。相比之下,传统凭证泄露多发生在代码提交或配置文件误传,而现在泄露发生在AI工具的“记忆”里。

更严重的是,这些日志会随着使用时间不断累积。使用AI编码工具越频繁,日志里积累的敏感信息就越多。一次性的测试密钥可能很快过期,但长期使用的服务密钥会一直躺在历史记录中。

开发者该如何扫描并清理已有泄露

首先需要找到日志位置。在Mac和Linux上,通常是~/.claude/projects/目录下的多个JSONL文件。可以使用grep结合常见凭证模式进行扫描,例如查找以sk-开头的OpenAI密钥、以AKIA开头的AWS密钥、或包含://的数据库URL。

审计者分享的CLI工具思路值得参考:递归读取所有JSONL,解析每条记录,提取工具调用结果部分,然后用正则匹配可能的凭证模式。找到后,不能简单删除整个日志,因为那会丢失AI会话历史。更好的做法是针对包含敏感信息的记录进行编辑或删除特定字段。

清理完成后,应该设置定期审计机制。可以在CI/CD流程中加入日志扫描步骤,或者用文件监控工具监视.claude目录的变化。至少每月手动或自动扫描一次,把发现的凭证立即轮换。

防护措施:限制AI代理能看到什么

最直接的办法是不要让AI代理直接读取真实凭证文件。可以在项目中准备一个.env.example文件,只包含变量名而没有真实值。当需要AI帮忙时,手动提供必要的非敏感上下文,而不是让它自己去cat真实文件。

另一个做法是使用环境变量隔离。把生产密钥放在系统环境变量里,而非项目目录下的.env文件。同时配置Claude Code的工具调用权限,限制它只能执行特定白名单命令,避免envprintenv这类会暴露全局信息的指令。

对于必须使用真实凭证的场景,可以考虑使用临时凭证或短期令牌。让AI只看到有效期很短的密钥,用完立即撤销。同时探索是否能通过Claude的设置或第三方工具来加密日志文件,或者配置自动清理超过一定时间的会话记录。

扩展到其他AI编码工具的通用风险

Claude Code不是唯一有这个问题的工具。类似Cursor、GitHub Copilot Workspace、Aider等AI辅助编程产品,都面临相同的本地上下文管理挑战。它们都需要把用户文件内容和命令输出保存下来以维持对话状态。

开发者在使用任何AI编码代理时,都应该先问三个问题:这个工具会读取哪些文件?这些内容会被存在哪里?存储的文件是否加密或有访问控制?目前多数工具对日志的安全处理仍然比较原始,依赖开发者自己提高警惕。

开源社区已经开始讨论制定“AI编码代理安全规范”,包括日志脱敏、最小权限原则、凭证自动检测等。一些工具开始提供“隐私模式”,在该模式下不记录包含敏感模式的内容,但效果还有待验证。

日常使用AI工具的最佳实践清单

  1. 永远不要在AI对话中直接粘贴完整凭证或命令输出。改用描述性语言,比如“我的数据库URL格式是postgres://user:password@host/db”,而非真实字符串。

  2. 把AI工作目录和真实项目目录分开。在一个干净的测试目录里复制必要代码(已脱敏),让AI在那里工作,完成后手动迁移修改。

  3. 定期审计所有AI相关隐藏目录,包括~/.claude~/.cursor等。编写或使用开源扫描工具,针对常见密钥格式进行匹配。

  4. 使用secret manager服务代替本地.env文件。让AI只看到从secret manager读取的临时值,而不是持久化凭证。

  5. 开启操作系统文件加密,特别是存放日志的目录。macOS的FileVault、Linux的eCryptfs都能提供额外保护。

  6. 养成“用完即删”的习惯。完成一个AI辅助任务后,如果不再需要历史上下文,就删除对应会话的JSONL记录。

  7. 在团队环境中,建立AI工具使用规范。明确哪些信息可以让AI看到,哪些必须严格隔离,并定期进行凭证轮换演练。

这些实践不能完全消除风险,但能大幅降低凭证在AI日志中长期泄露的可能性。AI编码工具正在成为开发者日常工作的一部分,伴随而来的安全责任也需要同步升级。

凭证泄露的真实后果与行业回应

历史上因为日志文件导致的凭证泄露已经多次发生。曾经有开发者把包含AWS密钥的终端日志上传到GitHub,结果被自动化扫描器发现并导致数万美元的云资源滥用账单。现在AI日志成了新的高危目标,因为它系统性地收集了开发者最敏感的信息。

目前Claude官方尚未对这一具体审计案例给出正式回应。但类似问题在AI编码领域已引发广泛讨论。一些安全研究者建议,未来AI代理应该在读取敏感文件前弹出明确警告,并在日志中自动对检测到的凭证进行哈希或脱敏处理。

对普通开发者来说,这个事件是个提醒:工具的便利性背后可能藏着意想不到的数据持久化行为。在享受AI大幅提升生产力的同时,必须把安全审计纳入常规工作流程。否则,下一个发现自家日志里躺着真实凭证的人,可能就不是主动审计的开发者,而是恶意攻击者。

参考来源