案例 大模型正在偷偷扒光你的底裤:Claude Code 安全防护指南

2026-05-05 19:06:51 +0800 CST views 5

大模型正在偷偷扒光你的底裤:Claude Code 安全防护指南

来源: 微信公众号
发布平台: 程序员茄子(chenxutan.com)
标签: AI安全, Claude Code, API密钥, 凭证泄露, 开发安全, settings.json


引言

你敢信?大模型正在偷偷扒光你的底裤。

Claude Code 一打开你的项目,就可能读取你的 .env 文件。

API key、数据库密码、Stripe token、各种生产凭证,只要写在 .env 里,就可能被加载进上下文,甚至出现在发送到 Anthropic 服务器的对话日志里。

更可怕的是,真正能阻止它访问这些文件的,往往只是一行 settings.json 配置。

而大多数人没有这行配置。

甚至根本不知道它存在。


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

很多人会在 CLAUDE.md 里写一句:

"永远不要读取 .env 文件。"

然后就以为自己安全了。

但其实并没有。

CLAUDE.md 更像是一条建议。大多数时候,Claude 会遵守它。可一旦任务复杂、上下文变长、指令变得模糊,它就可能忽略这种 advisory rule。

2026 年 4 月的一个 GitHub issue 曾确认过:即使 CLAUDE.md 明确禁止读取 .env,Claude 仍然可能读取并把 .env 内容回显到对话里。

真正可靠的保护

真正可靠的保护,是 settings.json 里的 deny rule

因为 deny rule 是系统级执行的。它会在 Claude 看到文件内容之前,就把访问拦下来。

这两者的区别很大:

保护方式机制可靠性
CLAUDE.md建议/规则❌ 可被忽略
settings.json系统级拦截✅ 物理上读不到

二、密钥泄露的3条路径

问题不只是 Claude 直接打开 .env

密钥泄露通常有三种路径

1. 直接读取文件

Claude 扫描项目,打开 .env,文件内容进入对话上下文。

这是最明显的风险,也是最容易用 deny rule 阻止的路径。

2. 运行时输出泄露

Claude 运行测试,或者启动你的应用。

某个失败的 HTTP 请求,把完整的:

Authorization: Bearer sk-live-abc123...

打印到了日志里。

或者数据库超时,把带密码的 connection string dump 了出来。

Claude 会捕获所有命令输出。

于是,哪怕它从来没有直接打开 .env,你的密钥也已经进入了对话。

3. Grep 和搜索工具泄露

Claude 用 grep 在代码库里搜索某个函数名。

结果匹配到了一个包含凭证的配置文件。

grep 输出把包含密钥的那几行也一起显示出来。

现在,密钥又进了上下文。


三、真正有用的 Deny Rules

把下面这些规则加到全局配置

~/.claude/settings.json

这样所有项目都会受到保护:

{
  "permissions": {
    "deny": [
      "Read(**/.env*)",
      "Read(**/.dev.vars*)",
      "Read(**/*.pem)",
      "Read(**/*.key)",
      "Read(**/secrets/**)",
      "Read(**/credentials/**)",
      "Read(**/.aws/**)",
      "Read(**/.ssh/**)",
      "Read(**/config/database.yml)",
      "Read(**/config/credentials.json)",
      "Read(**/.npmrc)",
      "Read(**/.pypirc)",
      "Write(**/.env*)",
      "Write(**/secrets/**)",
      "Write(**/.ssh/**)"
    ]
  }
}

这会阻止 Claude 读取或写入:

  • .env 文件
  • .dev.vars 文件
  • PEM 私钥
  • SSH key
  • AWS 配置
  • credential 文件
  • npm 和 PyPI token
  • secrets/credentials/ 目录

其中 ** 通配符表示:规则会应用到项目里的所有子目录。

这才是基础防线。

不是提醒 Claude 小心。

而是直接不给它看。


四、阻止运行时泄露

deny rules 能防止直接读文件。

但它挡不住运行时输出

所以,你还需要为测试准备专门的 .env.test,里面全部使用假值

.env.test 示例

# .env.test — 可以读取,也可以泄露,因为里面没有真密钥

STRIPE_SECRET_KEY=sk_test_not_a_real_key

DATABASE_URL=postgres://test:test@localhost:5432/testdb

OPENAI_API_KEY=sk-test-dummy-key-for-mocking

AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE

AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

配置测试框架

然后让你的测试框架读取 .env.test,而不是 .env

这样,当 Claude 运行测试并捕获输出时,就算日志里出现 key,也只是 dummy value

这一步很关键。

因为 Claude 不一定需要"偷看"你的密钥。

你的程序可能会自己把密钥打印出来。


五、用 Pre-commit Hook 做最后一道拦截

即使有 deny rules,错误也仍然可能发生。

所以,应该加一个 git pre-commit hook,在任何提交进入仓库之前扫描密钥。

Hook 脚本

#!/bin/bash

# .git/hooks/pre-commit — 阻止包含密钥的 commit

PATTERNS=(
  'sk-ant-'            # Anthropic API keys
  'sk-live-'          # Stripe live keys
  'sk_live_'          # Stripe live keys,另一种格式
  'ghp_'              # GitHub personal tokens
  'gho_'              # GitHub OAuth tokens
  'AKIA'              # AWS access keys
  'xox[bpors]-'       # Slack tokens
  'SG\.'              # SendGrid keys
  'eyJ'               # JWTs
  'BEGIN.*PRIVATE KEY' # Private key material
)

BLOCKED_FILES=('.env' 'credentials.json' 'id_rsa' '*.pem' '*.key')

for pattern in "${PATTERNS[@]}"; do
  if git diff --cached --diff-filter=ACM | grep -qE "$pattern"; then
    echo "BLOCKED: Found potential secret matching '$pattern'"
    echo "Remove the secret and try again."
    exit 1
  fi
done

for file in "${BLOCKED_FILES[@]}"; do
  if git diff --cached --name-only | grep -q "$file"; then
    echo "BLOCKED: Attempted to commit sensitive file: $file"
    exit 1
  fi
done

echo "Pre-commit security check passed."
exit 0

启用 Hook

chmod +x .git/hooks/pre-commit

这个 Hook 会拦截

  • Anthropic API keys (sk-ant-)
  • Stripe live keys (sk-live-, sk_live_)
  • GitHub tokens (ghp_, gho_)
  • AWS keys (AKIA)
  • Slack tokens (xox[bpors]-)
  • SendGrid keys (SG.)
  • JWT (eyJ)
  • 私钥内容 (BEGIN.*PRIVATE KEY)

只要这些东西出现在 staged file 里,commit 就会被阻止。

这不是完美安全。

但它能拦住很多非常真实、非常低级、也非常昂贵的事故。


六、容器隔离:核按钮方案

如果你要最大限度安全,可以把 Claude Code 放进容器里运行,并且让容器里根本不存在 .env

Docker 方案

# 把 /dev/null 挂载到 /app/.env,这样 Claude 看不到真实 .env

docker run -v /dev/null:/app/.env:ro your-dev-container

从 Claude 的视角看,.env 就是一个空文件

你的真实密钥从一开始就没有进入容器文件系统。

对大多数项目来说,这可能有点过度。

但如果你在做客户项目,尤其项目里有生产凭证,这个方案就很值得考虑。


七、完整安全配置:直接复制版

下面是完整的 ~/.claude/settings.json

{
  "permissions": {
    "allow": [
      "Read",
      "Glob",
      "Grep",
      "LS",
      "Edit",
      "MultiEdit",
      "Write(src/**)",
      "Write(tests/**)",
      "Bash(npm run *)",
      "Bash(npm test *)",
      "Bash(npx tsc *)",
      "Bash(git status)",
      "Bash(git diff *)",
      "Bash(git log *)",
      "Bash(git add *)",
      "Bash(git commit *)"
    ],
    "deny": [
      "Read(**/.env*)",
      "Read(**/.dev.vars*)",
      "Read(**/*.pem)",
      "Read(**/*.key)",
      "Read(**/secrets/**)",
      "Read(**/credentials/**)",
      "Read(**/.aws/**)",
      "Read(**/.ssh/**)",
      "Read(**/config/database.yml)",
      "Read(**/config/credentials.json)",
      "Read(**/.npmrc)",
      "Read(**/.pypirc)",
      "Write(**/.env*)",
      "Write(**/secrets/**)",
      "Write(**/.ssh/**)",
      "Write(.github/workflows/*)",
      "Bash(rm -rf *)",
      "Bash(sudo *)",
      "Bash(git push *)",
      "Bash(npm publish *)",
      "Bash(curl * | sh)",
      "Bash(wget *)",
      "Bash(chmod *)"
    ],
    "defaultMode": "acceptEdits"
  }
}

这份配置做了什么?

第一,它允许日常开发里常见的操作:

  • 读取文件
  • 编辑源码
  • 运行测试
  • 查看 git diff
  • 提交 commit

第二,它拒绝

  • 敏感文件访问(.env、secrets、ssh)
  • 危险操作(rm -rfsudogit pushnpm publish
  • 执行管道安装脚本(curl | sh

一句话总结

让 Claude 能干活。
但别让它碰不该碰的东西。


八、使用前检查清单

下次打开 Claude Code 前,先问自己 6 个问题

#问题检查
1你的 settings.json 里是否有针对 .env 文件的 deny rules?
2你的测试是否使用带 dummy values 的 .env.test?
3你的项目是否有 pre-commit hook 扫描密钥模式?
4生产凭证是否放在 vault 里,而不是明文文件中?
5.env 是否已经加入 .gitignore?
6.env 文件是否放在项目目录之外,以获得额外安全性?

如果这 6 项你都做了,你的密钥已经尽可能安全。

如果 0 项都没做,那你距离 API key 出现在 Anthropic 服务器上的 conversation log 里,可能只差一次模糊的 Claude prompt。


九、常见问题

Q1:deny rules 会影响 Claude 正常工作吗?

不会。deny rules 只拦截你明确指定要保护的敏感文件。正常的代码文件不受影响。

Q2:可以只保护特定项目而不是全局吗?

可以。在项目根目录创建 .claude/settings.json,只会影响当前项目。

Q3:已经有泄露怎么办?

  1. 立即轮换所有密钥:API key、数据库密码、Stripe token 等
  2. 检查日志:看是否有异常访问
  3. 启用 deny rules:防止再次泄露
  4. 检查 git 历史:确保没有把密钥提交到仓库

Q4:还有其他需要保护的文件吗?

文件类型说明
.env环境变量(API keys、密码)
.npmrcnpm token
.pypircPyPI token
.aws/AWS 凭证
.ssh/SSH 私钥
*.pemSSL 证书私钥
credentials.json数据库/服务凭证
secrets/密钥目录

十、总结

AI 工具带来了巨大的生产力提升,但同时也带来了新的安全风险。

密钥泄露不是"会不会"的问题,而是"什么时候"的问题。

防御层次:

层次措施优先级
第一层settings.json deny rules⭐⭐⭐⭐⭐
第二层.env.test 隔离测试⭐⭐⭐⭐
第三层pre-commit hooks⭐⭐⭐⭐
第四层容器隔离⭐⭐⭐

多层防御,才能让你的密钥真正安全。


本文首发于「程序员茄子」博客,原文链接:https://chenxutan.com

推荐文章

Nginx 如何防止 DDoS 攻击
2024-11-18 21:51:48 +0800 CST
Golang 中应该知道的 defer 知识
2024-11-18 13:18:56 +0800 CST
JavaScript设计模式:桥接模式
2024-11-18 19:03:40 +0800 CST
Vue3中如何扩展VNode?
2024-11-17 19:33:18 +0800 CST
Vue中的样式绑定是如何实现的?
2024-11-18 10:52:14 +0800 CST
go命令行
2024-11-18 18:17:47 +0800 CST
Boost.Asio: 一个美轮美奂的C++库
2024-11-18 23:09:42 +0800 CST
Python实现Zip文件的暴力破解
2024-11-19 03:48:35 +0800 CST
Nginx rewrite 的用法
2024-11-18 22:59:02 +0800 CST
程序员茄子在线接单