防止 Claude Code 泄露密钥的 .env 配置指南(含完整配置)

防止 Claude Code 泄露密钥的 .env 配置指南(含完整配置)

@zodchiii
英语2周前 · 2026年4月30日

AI 功能

1.7M
1.3K
149
30
5.9K

TL;DR

学习如何通过配置 settings.json 拒绝规则、使用虚拟测试环境以及实施 pre-commit hooks 来保护 Claude Code,从而防止敏感凭据泄露。

Claude Code 在打开你的项目时就会读取你的 .env 文件。

你的 API 密钥、数据库密码、Stripe 令牌——.env 文件中的所有内容都会被加载到内存中,并可能最终出现在发送给 Anthropic 服务器的对话日志中。

唯一真正能阻止访问的,是 settings.json 中的一行规则,而大多数人既没有设置它,也不知道它的存在。

以下是完整的安全配置 👇

在深入之前,我每天会在我的 Telegram 频道分享关于 AI 和 vibe coding 的笔记:**https://t.me/zodchixquant**🧠

darkzodchi on X — cover

为什么 CLAUDE.md 规则保护不了你

大多数人在 CLAUDE.md 中添加了"永远不要读取 .env 文件"的规则,就以为安全了(其实不然)

CLAUDE.md 只是一个建议。Claude 大部分时间会遵循它,但在压力下(复杂任务、长上下文、模糊指令),它可能会忽略这些建议性规则。

一个 2026 年 4 月的 GitHub issue 证实:即使 CLAUDE.md 明确禁止,Claude 仍然会读取 .env 内容并将其回显到对话中。

唯一可靠的保护是 settings.json 中的拒绝规则。拒绝规则在系统层面强制执行,在 Claude 看到文件之前就已经生效。

区别在于"请不要读取这个"和"你根本无法读取这个"。

darkzodchi - inline image

你的秘密泄露的 3 种方式

问题不仅仅是 Claude 直接读取 .env。有三种途径:

1. 直接文件读取。 Claude 扫描你的项目,打开 .env,内容成为对话上下文的一部分。这是最明显的途径,也是最容易通过拒绝规则阻止的。

2. 运行时输出捕获。 Claude 运行你的测试或启动你的应用。一个失败的 HTTP 请求会记录完整的 Authorization: Bearer sk-live-abc123... 头。数据库超时会输出包含密码的连接字符串。Claude 捕获所有命令输出。你的秘密现在就在对话中,即使 Claude 从未打开 .env。

3. Grep 和搜索工具。 Claude 使用 grep 搜索你的代码库以查找函数名。搜索命中了一个包含凭据的配置文件。grep 输出中包含匹配的行,你的秘密一览无余。

大多数人只防范了途径 1。途径 2 和 3 才是真正造成损害的地方。

真正有效的拒绝规则

将这些添加到 ~/.claude/settings.json 中,以实现对所有项目的全局保护:

json

json
1{
2 "permissions": {
3 "deny": [
4 "Read(**/.env*)",
5 "Read(**/.dev.vars*)",
6 "Read(**/*.pem)",
7 "Read(**/*.key)",
8 "Read(**/secrets/**)",
9 "Read(**/credentials/**)",
10 "Read(**/.aws/**)",
11 "Read(**/.ssh/**)",
12 "Read(**/config/database.yml)",
13 "Read(**/config/credentials.json)",
14 "Read(**/.npmrc)",
15 "Read(**/.pypirc)",
16 "Write(**/.env*)",
17 "Write(**/secrets/**)",
18 "Write(**/.ssh/**)"
19 ]
20 }
21}

这会阻止 Claude 读取或写入任何 .env 文件、PEM 密钥、SSH 密钥、AWS 配置、凭据文件以及 npm/PyPI 令牌。** 通配符意味着它适用于项目中的每个子目录。

阻止运行时泄露

拒绝规则可以阻止直接文件读取,但无法阻止运行时输出。为此,请使用包含虚拟值的测试专用 .env 文件:

text
1# .env.test — 可安全读取,可安全泄露
2STRIPE_SECRET_KEY=sk_test_not_a_real_key
3DATABASE_URL=postgres://test:test@localhost:5432/testdb
4OPENAI_API_KEY=sk-test-dummy-key-for-mocking
5AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
6AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

将你的测试框架指向 .env.test 而不是 .env。这样当 Claude 运行你的测试并捕获输出时,唯一可见的密钥都是虚拟的。

能捕获一切的 pre-commit 钩子

即使有拒绝规则,错误仍可能发生。添加一个 git pre-commit 钩子,在每次提交到达仓库之前扫描秘密:

bash

bash
1#!/bin/bash
2# .git/hooks/pre-commit — 阻止包含秘密的提交
3
4PATTERNS=(
5 'sk-ant-' # Anthropic API 密钥
6 'sk-live-' # Stripe 生产密钥
7 'sk_live_' # Stripe 生产密钥(另一种格式)
8 'ghp_' # GitHub 个人令牌
9 'gho_' # GitHub OAuth 令牌
10 'AKIA' # AWS 访问密钥
11 'xox[bpors]-' # Slack 令牌
12 'SG\.' # SendGrid 密钥
13 'eyJ' # JWT
14 'BEGIN.*PRIVATE KEY' # 私钥材料
15)
16
17BLOCKED_FILES=('.env' 'credentials.json' 'id_rsa' '*.pem' '*.key')
18
19for pattern in "${PATTERNS[@]}"; do
20 if git diff --cached --diff-filter=ACM | grep -qE "$pattern"; then
21 echo "已阻止:发现潜在秘密匹配 '$pattern'"
22 echo "请移除秘密后重试。"
23 exit 1
24 fi
25done
26
27for file in "${BLOCKED_FILES[@]}"; do
28 if git diff --cached --name-only | grep -q "$file"; then
29 echo "已阻止:尝试提交敏感文件:$file"
30 exit 1
31 fi
32done
33
34echo "Pre-commit 安全检查通过。"
35exit 0

使其可执行:chmod +x .git/hooks/pre-commit

这会捕获 Anthropic API 密钥、Stripe 密钥、GitHub 令牌、AWS 密钥、Slack 令牌、SendGrid 密钥、JWT 和私钥材料。如果这些中的任何一个出现在暂存文件中,提交将被阻止。

容器隔离(终极方案)

为了最大安全性,在容器内运行 Claude Code,其中 .env 文件根本不存在:

bash

bash
1# 将 /dev/null 挂载到 .env 上,使 Claude 无法看到它
2docker run -v /dev/null:/app/.env:ro your-dev-container

从 Claude 的角度看,.env 是一个空文件。你的秘密永远不会进入容器文件系统。这对大多数项目来说有些过度,但对于涉及生产凭据的客户工作来说至关重要。

完整安全配置(可直接复制使用)

完整的 ~/.claude/settings.json,包含所有安全保护:

json

json
1{
2 "permissions": {
3 "allow": [
4 "Read",
5 "Glob",
6 "Grep",
7 "LS",
8 "Edit",
9 "MultiEdit",
10 "Write(src/**)",
11 "Write(tests/**)",
12 "Bash(npm run *)",
13 "Bash(npm test *)",
14 "Bash(npx tsc *)",
15 "Bash(git status)",
16 "Bash(git diff *)",
17 "Bash(git log *)",
18 "Bash(git add *)",
19 "Bash(git commit *)"
20 ],
21 "deny": [
22 "Read(**/.env*)",
23 "Read(**/.dev.vars*)",
24 "Read(**/*.pem)",
25 "Read(**/*.key)",
26 "Read(**/secrets/**)",
27 "Read(**/credentials/**)",
28 "Read(**/.aws/**)",
29 "Read(**/.ssh/**)",
30 "Read(**/config/database.yml)",
31 "Read(**/config/credentials.json)",
32 "Read(**/.npmrc)",
33 "Read(**/.pypirc)",
34 "Write(**/.env*)",
35 "Write(**/secrets/**)",
36 "Write(**/.ssh/**)",
37 "Write(.github/workflows/*)",
38 "Bash(rm -rf *)",
39 "Bash(sudo *)",
40 "Bash(git push *)",
41 "Bash(npm publish *)",
42 "Bash(curl * | sh)",
43 "Bash(wget *)",
44 "Bash(chmod *)"
45 ],
46 "defaultMode": "acceptEdits"
47 }
48}

这是我上一篇文章中的 settings.json 加上本文中的所有安全规则。允许规则用于日常工作流程,拒绝规则用于秘密和危险操作。一个文件,全面保护。

检查清单

在下次使用 Claude Code 之前:

  1. 你的 settings.json 中是否有针对 .env 文件的拒绝规则?
  1. 你的测试是否使用包含虚拟值的 .env.test?
  1. 是否有 pre-commit 钩子扫描秘密模式?
  1. 生产凭据是否存储在保险库中,而不是明文文件中?
  1. .env 是否在 .gitignore 中?
  1. .env 文件是否位于项目目录之外以获得额外安全性?

如果你检查了全部 6 项,你的秘密就得到了最大程度的保护。如果你检查了 0 项,那么你离你的 API 密钥出现在 Anthropic 服务器上的对话日志中,只差一个模糊的 Claude 提示。

我每天在我的 Telegram 频道分享关于 AI、金融和 vibe coding 的笔记:**https://t.me/zodchixquant**

感谢阅读🙏🏼

darkzodchi - inline image

更多可拆解样本

近期爆款文章

探索更多爆款文章

为创作者而生。

从全球 𝕏 爆款文章里发现选题,拆解它为什么能爆,再把可复用的内容结构变成你的下一篇创作灵感。