Tips & Tricks (更新: 2026/6/7)

Claude Code 安全防护总览|用 6 个观点止住事故的检查清单

把 Claude Code 与 AI 辅助开发的安全对策一图看全:权限、密钥、危险命令、依赖、输入、日志六个观点,配可复制的配置和清单,各论见内部链接。

Claude Code 安全防护总览|用 6 个观点止住事故的检查清单

安全方面的文章我读了十来篇,可自己的项目到底安不安全,最后还是一头雾水。

我也一样。“API 密钥放环境变量”“权限给最小”——这些大道理我哪条不知道。可知识全是散落的点,拼不到一起,根本答不上来“那我现在到底漏了啥”。每次都是出了事,才一拍脑门:“啊,那篇文章里写过的就是这个。”这种亏我吃过好几回。

所以这篇文章,要把 AI 辅助开发的安全做成一张地图。细的步骤留给各论,这里只让你能从上往下扫一眼,看清“哪个观点漏了”。要守的地方,就六个。一个个堵上,哪怕你半夜把活儿丢给 AI,早上也不会看到终端一片惨白。

这篇是从防守方的角度写的。讲的不是怎么攻击,而是怎么把东西做得“挨了打也不塌”。

本文要点

  • AI 辅助开发的事故,基本都从这六个洞里钻进来:权限、密钥、危险命令、依赖与输入、日志、生产隔离
  • 最管用的不是“多小心点”,而是“就算不小心也会被拦下的机制”。.claude/settings.jsondeny.gitignore,是两条救命绳。
  • 先堵的优先级是:(1) 别把密钥交给 AI、别提交进仓库 (2) 用 deny 拦住危险命令 (3) 把读写的范围收窄。做到这里,重大事故的绝大多数就消失了。
  • 各论我都放进了内部链接。这篇文章请当成“查漏补缺用的检查清单”来用。
  • 文末放了一份可整段复制的 settings.json 和确认用的命令。

为什么一“交给 AI”就突然变危险

普通的文本编辑器,只是把字显示出来而已。没有坑。

可像 Claude Code 这样的 AI 智能体,是在你电脑里动手干活的工具。读文件、写文件、删文件。在终端里敲命令。上网,往外部服务上发东西。而且这些,只要你点一次“是”就动。

问题在于,确认按钮按上几十回之后,你就不看内容了。一旦顺进“行行行,OK”的节奏,危险操作就悄没声儿地溜过去了。就像菜刀越锋利,没学会怎么拿之前越容易割到手。它手又快又聪明,往错的方向也是全力狂奔。

所以这里,请你把对策的思路彻底掉个个儿。别想着“我自己小心点”,而是**“先搭好就算我走神也不出事的机制”**。这张地图的六个观点,全是按这个思路排的。

安全总览:要守的地方就六个

先用一张表看全。哪个观点守的是什么,从上往下扫一遍。

#观点防的事故举例主要工具各论
1收窄权限擅自改写、删除settings.json 的 allow/ask/deny权限指南
2别把密钥交出去/提交进仓库API 密钥泄露.gitignore、环境变量、打码密钥管理
3拦住危险命令rm -rf、force pushdeny 规则危险指令的规避
4校验依赖与输入供应链、注入lockfile、schema 校验(本文)
5别把密钥留在日志里从历史泄露打码、输出控制密钥管理
6把生产单独对待生产数据库被毁环境隔离、标志失败案例

这六个看着各自独立,其实是一根线串起来的:“让 AI 看什么、让它做什么、在哪儿拦住、怎么核实”。把能看的范围收窄(1、2),把能做的操作限死(3),对进来的东西保持怀疑(4),不留痕迹(5),唯独生产要特殊对待(6)。下面一个个看。

观点 1:收窄权限——只读放行,删除禁止

第一道防线是权限。Claude Code 能按操作逐条决定“OK/要确认/禁止”。在 .claude/settings.jsonpermissions 里,把操作往三个箱子里一分就行。

箱子含义往里放啥
allow不确认就执行只读的安全操作
ask每回好好问写入、提交、推送
deny一概不许删除、force push、生产数据库

口诀就一句:只读放 allow,要写放 ask,要删放 deny

要紧的是起步的方向。一开始卡得死死的,等哪个操作确认了“噢,这个安全”,再往后升级。反着来(先松后紧),一定是出了事故才动手。所以务必从“收紧”这头起步。allowdenyask 的判定顺序,以及 BashEditReadWebFetch 各自的模式语法这些细节,我在 Claude Code 权限设置指南里做成了速查表。

另外,现在的 Claude Code 在这三类之外,还有按危险程度机械判定的自动放行模式(auto mode)等机制。具体行为以官方为一手信息,抠配置时请务必查阅官方设置文档

观点 2 和 5:别把密钥交出去、别提交、别留在日志里

泄露基本上从三条路发生:写死在代码里、直接递给 AI、留在日志里。 全堵上。

先别写死,把钥匙隔离进 .env。然后声明让 Git“绝对不要捡起”这个 .env。这是救命绳。

# 必须写进 .gitignore(防止手滑把钥匙提交上去的保险)
.env
.env.*
!.env.example   # 只有示例文件可以共享
*.pem
*.key
*-service-account.json   # 云服务的服务账号密钥也别忘

代码里不直接写文件里的值,而是当成环境变量读进来。做到钥匙的真身在代码任何地方都不出现。

// OK: 从环境变量读。值一个字都不写进代码
import { config } from "dotenv";
config();

const token = process.env.QIITA_TOKEN;
if (!token) {
  // 没钥匙的话,不报值,只提醒“你忘配了”
  throw new Error("QIITA_TOKEN 没设置。请检查 .env。");
}

接着是“直接递给 AI”和“留在日志里”。想让它修报错,把日志整段贴上去,里头没准就混着一行 DATABASE_URL=postgresql://user:真实的密码@...。递出去那一刻,对话历史里、子智能体的历史里,都留下了明文密钥。所以报错输出里、递给 AI 的日志里,都别让值露出来。

// NG: 报错日志里 API 密钥原样露出来
throw new Error(`认证失败: token=${process.env.TOKEN}`);

// OK: 不报值,只告诉该看哪儿
throw new Error("认证失败: 请检查 TOKEN 环境变量");

给 AI 递日志时,把带钥匙的那几行换成打码再递。AI 只要看懂“这儿有个数据库连接信息”的结构,就能干活。

能递不能递
报错的类型、复现步骤、文件名API 密钥、密码、会话 cookie
.env.example、配置项的“名字”生产数据库的 URL、客户的数据
换成打码的日志真实令牌、服务账号的 .json 文件

.env 本身设成“连读都不许”,会更稳(观点 3 里细说)。让它读 .env 的事故,一行配置就能根绝。从 CI/CD 里的处理到生产密钥的轮换,整套步骤我写在了 Claude Code 的密钥管理里。

观点 3:拦住危险命令——把覆水难收的操作物理封死

rm -rf(一键删除)、git push --force(覆盖团队工作)、git reset --hard(丢弃改动)。这些都覆水难收。别只设成“执行前必问人”,初期直接倒向“压根不许执行”。

这里管用的,是和观点 2 的“禁止读取”合在一起的 deny

"deny": [
  "Read(./.env)",
  "Read(./.env.*)",
  "Read(./secrets/**)",
  "Bash(rm -rf*)",
  "Bash(git push --force*)",
  "Bash(git reset --hard*)",
  "Bash(curl * | bash)"
]

看最后那条 Bash(curl * | bash)。它的意思是“从网上抓个脚本,不看内容就直接跑”。安装步骤里常见这种写法,但在 AI 辅助开发里尤其危险。它直接连着观点 4 的供应链,所以初期先拦住。

而且,不光在配置文件里拦,还要在 CLAUDE.md(项目规矩)里用大白话把意图也写一遍。机械的拦截 + 给 AI 的说明,两道防线一摆,漏网的就少了。

## 禁止编辑和执行的事(写进 CLAUDE.md)

- 不读 .env / secrets/ 。需要时务必先问人类确认。
- 不执行 rm -rf、force push、往生产数据库写入。
- 不把从网上抓来的脚本不看就执行。

“一句含糊的话怎么招来 AI 暴走”,以及怎么把请求本身写安全的套路,我整理在了“全交给你”招来的事故,以及怎么防里。用配置去约束,和改变求它的方式,是一对轮子。

观点 4:校验依赖与输入——对 AI 带来的东西保持怀疑

这一点,恰恰是传统安全文章容易写薄的地方。一交给 AI,你没写过的代码、你没核实过的输入,就流进了项目。

第一个是依赖(供应链)。AI 会面不改色地“这个库我给你装上哈”,敲个 npm install。可包名没准跟正版差一个字(typosquatting,仿冒包名),或者是个早没人维护的老货。所以依赖要放进“人来确认”的 ask,并把 lockfile 提交进仓库锁住版本。在 CI 里挂上审计,已知漏洞就会被自动逮住。

# 机械地检查依赖里有没有已知漏洞
npm audit --audit-level=high

# 严格按 lockfile 固定安装(防止擅自更新版本)
npm ci

第二个是输入。AI 生成的代码,要是把外来的值(用户输入、API 的响应、文件内容)照单全收地拿去用,就危险了。SQL 注入、命令注入,根子都在这个“不怀疑输入”上。要在边界处必校验类型和形状。

import { z } from "zod";

// 外来的值,要在边界处必校验形状是否正确
const Payload = z.object({
  email: z.string().email(),
  amount: z.number().int().positive().max(100000),
});

// 过不了 parse 的输入,当场就弹掉(不往后续的数据库处理里递)
const safe = Payload.parse(await req.json());

依赖与输入的校验,和 Web 应用整体的安全是连成一片的。代表性攻击的分类,OWASP Top Ten是业界标准的检查清单,过一遍能帮你发现观点上的疏漏。

观点 6:把生产单独对待——为了不让一字之差删光一切

最后一条。myapp_devmyapp_prod,就差一个字。只甩一句“把旧数据清掉”,AI 又没确认自己连的是哪个——被清掉的,没准就是生产里客户的数据。

所以往生产写入,要逼它多走一道手续。这份麻烦,就是救命绳。

// scripts/db-query.mjs
const env = process.env.NODE_ENV ?? "development";

// 想往生产写入时,没有专用标志就拦下
if (env === "production" && process.argv.includes("--write")) {
  console.error("往生产写入需要 --force-production 标志。");
  process.exit(1);
}

生产数据库真被吹飞的案例、CI 暴走的案例——这些生猛失败的成因、抢救、复发防止,我都整理在了 Claude Code 安全失败案例里。别人的事故,是你能买到的最便宜的教训。

可整段复制:把六个观点塞进一份 settings.json

把上面这六个观点,整个塞进了一个文件。当成 .claude/settings.json 放进去就能用。按你自己的环境增删即可。

{
  "$schema": "https://json.schemastore.org/claude-code-settings.json",
  "permissions": {
    "defaultMode": "default",
    "allow": [
      "Read(**)",
      "Glob(**)",
      "Grep(**)",
      "Bash(npm run lint*)",
      "Bash(npm run test*)"
    ],
    "ask": [
      "Write(**)",
      "Edit(**)",
      "Bash(npm install*)",
      "Bash(git commit*)",
      "Bash(git push*)"
    ],
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./secrets/**)",
      "Bash(rm -rf*)",
      "Bash(git push --force*)",
      "Bash(git reset --hard*)",
      "Bash(curl * | bash)"
    ]
  }
}

装好没有,用三条命令确认。

# 1. .env 是否已脱离 Git 管理(什么都不输出 = 没被追踪 = OK)
git ls-files --error-unmatch .env

# 2. 有没有手滑把钥匙提交过,朴素地搜一遍历史
git grep -nE "(api[_-]?key|secret|token|password)\s*=\s*['\"][A-Za-z0-9]" $(git rev-list --all) -- . || echo "没发现明显的写死"

# 3. 依赖里有没有已知漏洞
npm audit --audit-level=high

第 1 条里 .env 若报错,说明“没被追踪”,安全。第 2 条是朴素搜索,不万能,但明显的写死能逮着。第 3 条若冒出高风险,就把依赖升级或换掉。

整体检查清单

打开项目后,从上往下确认。哪怕有一条没打勾,那儿就是你下一个洞。

  • .claude/settings.json,且 deny 里有 rm -rf 和 force push(观点 1、3)
  • 只读是 allow,写入类是 ask(观点 1)
  • .gitignore 里有 .env 和钥匙文件(*.pem *.key *-service-account.json)(观点 2)
  • 钥匙没写死进代码、prompt,而是从环境变量读(观点 2)
  • deny.envsecrets/ 设成禁止读取(观点 2、5)
  • 报错输出、递给 AI 的日志里,不露钥匙的值(观点 5)
  • npm install 设成 ask,提交 lockfile,把 npm audit 放进 CI(观点 4)
  • 用 schema 校验外部输入(观点 4)
  • 往生产写入加了标志之类的一道手续(观点 6)
  • CLAUDE.md 里用大白话写了“禁止的事”和“能递/不能递”(全观点)

常见问题

Q. 一大堆,太累了。最初的 30 分钟该优先做啥? A. 上面三条就够。(1) 建 .env 把钥匙挪进去并加进 .gitignore (2) 在 .claude/settings.jsondeny 里塞进 rm -rf.env 的读取 (3) 把写入类设成 ask。光这些,重大事故的绝大多数(密钥泄露、生产删除)就止住了。剩下的慢慢来不迟。

Q. 那种“全交给你”、不确认就能执行的模式,能用吗? A. 只在可信的隔离环境(用完即弃的容器、专用沙箱)里用。在自己的主力机、或连着生产的环境里跳过确认,等于拆了辅助轮去冲下坡。便利和覆水难收,永远是背靠背的。

Q. 明明加进了 deny,换个写法的命令会不会绕过去? A. 模式匹配不万能,换种写法的绕路是可能的。所以别把 deny 当“最后一道墙”过度信任,要叠上 CLAUDE.md 里的意图明文、生产隔离(观点 6)、人工的 ask 确认,多层去守。诀窍不是摆一道墙,而是摆好几道。

Q. AI 装的库,每回都查,现实吗? A. 全部肉眼看是不可能的。所以交给机器。把 npm install 设成 ask,瞄一眼名字,再把 npm audit 放进 CI,已知漏洞自动弹掉。人只看“名字怪不怪”,深的检查甩给机器——这才是能坚持下去的诀窍。

Q. 个人的兴趣项目,也要做到这份上吗? A. 唯独密钥泄露,兴趣项目也请认真防。一发到 GitHub,钥匙瞬间就被全世界的 bot 捡走。反过来,生产隔离(观点 6),没有生产的兴趣项目省了也行。每个观点都按“跟我有没有关系”取舍,就够了。

小结

AI 辅助开发的安全,拼的不是难知识的量。是把六个洞,从上往下一个个堵上的活儿。

观点一句话主要的招
1. 收窄权限只读放行allow/ask/deny
2. 别把密钥交出去钥匙放在代码外.env + .gitignore
3. 拦住危险命令删除禁止deny 规则
4. 校验依赖与输入怀疑带进来的东西audit + schema 校验
5. 别留在日志里抹掉痕迹不输出值、打码
6. 把生产单独对待防一字之差环境隔离、标志

思路从头到尾就一个。别再靠“多小心”,而是先搭好“不小心也会被拦下的机制”。与其费劲去驾驭一个聪明 AI,不如先把“摔了也不会受伤”的地板铺好。这是我现在的结论——最省力,也最快。

把这篇文章收藏好,每开一个新项目,就把检查清单从上往下过一遍。想深挖某个观点,就从正文的内部链接去各论。要是拿不准团队该卡到哪一步,我也备了教程和支持。先来 教程一览 瞧一瞧吧。

#claude-code #security #permissions #secrets #checklist #best-practices
免费

免费 PDF: Claude Code 速查表

输入邮箱即可获取一页 PDF,整理常用命令、审查习惯和安全工作流。

我们会妥善保护你的信息,不发送垃圾邮件。

让 Claude Code 真正进入可验证的工作流

先用免费 PDF 固定基础,再用 Gumroad 教材复用工作流;如果涉及团队导入、权限或收入路径,可以直接咨询。

Masa

关于作者

Masa

专注 Claude Code 实务流程、团队导入和内容转化的工程师。