🐎 第10章 炉火纯青:工程化实战
📄 一句话概括

六条准则都能落到具体字段上:权限模式、工具权限、文件访问、钩子、MCP 来源、密钥。 实测三份配置:过 1、4、5 条,没有一份满分。最严格那份栽在「把密钥打进日志」。

📝 本章和前面几章的关系

上一节讲出事之后怎么查,这一节讲怎么让它从一开始就不越界。 这一节有真跑:三份配置文件,六条准则逐条查,看哪条最容易漏。

一、六条准则对应的字段

权限模式:不能是「全部放行」。那等于一开场就不问你了,后面所有拦截都失效。 工具权限:允许清单里不能出现裸的命令执行。裸的等于把整台机器交出去。 文件访问:忽略清单要覆盖密钥文件和数据目录。读进去就等于泄出去了。

钩子扫描:钩子里不许把密钥打进日志。这条最不像安全问题,也最容易漏。 MCP 信任:服务器要固定版本。用即时拉取的方式装,装到的是什么没人知道。 密钥管理:走环境变量,不写进配置文件。配置文件会被提交、被拷走、被贴进聊天窗口。

六条的共同点是「能机器检查」。检查不了的准则只是希望,不是底线。

二、真跑:三份配置逐条查

三份配置:A 宽松(全部放行、裸命令、无忽略、明文密钥)、B 中等(有忽略但只一项、密钥明文)、 C 严格(计划模式、带限定的命令、三项忽略)。 结果:A 过一条、B 过四条、C 过五条。没有一份满分。 A 那一条是「钩子里没打密钥」——但它是恰好没事,因为它的钩子只有一句 echo。改一次钩子就漏。

这种「恰好没事」比「明确没做」更危险:前者让人以为自己已经考虑过了。

三、第四条为什么最容易漏

漏掉这条的是 C——那份看起来最严格的配置。 因为它写了一行把密钥打进审计日志的命令。写的人想的是「留证据」,不是「泄露」。 而且它比写进配置文件更隐蔽:配置文件会被审查,日志不会;配置文件只在自己机器上,日志会进集中收集。

判据很简单:钩子里凡是出现带 KEY、TOKEN、SECRET 字样的变量,一律当泄露处理。 要留证据就留「用了哪个密钥的代号」,不要留密钥本身。

四、六条之间的关系

前三条是「别让它做不该做的」,后三条是「别让东西流出去」。 两组要一起做:只做前三条,它不越界但会泄密;只做后三条,东西不漏但它能乱来。 这与 8.8 节那四道防线是同一条思路:单条都拦不住,叠起来才有纵深。

也别指望某一条特别强就够——最强的往往是最容易被绕过的那条,因为它最惹眼。

五、查配置这件事要自动化

手查一定会漏,因为六条散在四个文件里,而且字段名不一样。 写成脚本,每次改配置跑一遍。这个脚本本身就该挂在提交前的钩子上。 更彻底的做法是把它放进团队的共享配置里,让所有人装的时候就带着。

这正好接上第 9 章:能装、能升、能审的东西,才配叫「底线」。

六、动手 Demo:三份配置按六条准则查,没有一份满分

三份配置覆盖三种风格:全部放行、中等收紧、尽量严格。六条准则逐条判,输出一张表。 注意最严格那份在哪一条上栽了。

leak = [h for h in cfg[u"hooks"]
        if re.search(r"\$\{?\w*(KEY|TOKEN|SECRET)\w*", h)]
out.append((u"Hook 扫描", not leak,
            u"打进日志" if leak else u"只记结果"))

实跑输出:

--------------------------------------------------------------------
三份配置按六条准则查,没有一份满分
--------------------------------------------------------------------

  安全准则不是「记得做」,是「能逐条查」。六条落到配置上,每条都有对应的字段。
  这里拿三份配置过一遍,看哪条最容易漏。

  ① 六条准则对应的字段
  --------------------------------------------------------------------
| 准则 | 落到哪 | 为什么 |
|---|---|---|
| 权限模式 | defaultMode 不能是 bypass | 一开场就不问你了 |
| 工具权限 | allow 里不能有裸 Bash | 裸 Bash 等于给了整台机器 |
| 文件访问 | ignore 覆盖密钥与数据目录 | 读进去就等于泄出去了 |
| Hook 扫描 | 钩子里不许打密钥 | 日志留得久、看的人多 |
| MCP 信任 | 服务器要固定版本 | 即时拉包,装的是什么不知道 |
| 密钥管理 | 走环境变量,不写进文件 | 文件会被提交、被拷走 |


  ② 真跑:三份配置逐条查
  --------------------------------------------------------------------
  表头 1 到 6 就是上表的六条,顺序一样。
| 配置 | 1 | 2 | 3 | 4 | 5 | 6 | 合计 |
|---|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| A 宽松 | 漏 | 漏 | 漏 | 过 | 漏 | 漏 | 1/6 |
| B 中等 | 过 | 过 | 漏 | 过 | 过 | 漏 | 4/6 |
| C 严格 | 过 | 过 | 过 | 漏 | 过 | 过 | 5/6 |

  三份分别过 1、4、5 条,没有一份满分。
  最宽松那份只过一条:它没往日志里打密钥,但那是因为它的钩子只有一句 echo 完成,
  不是因为写配置的人想到了这一条。这种「恰好没事」最危险,改一次钩子就漏。
  最严格那份栽在第四条——它写了一行把密钥打进审计日志的命令。

  ③ 第四条为什么最容易漏
  --------------------------------------------------------------------
  漏掉这条的是:C 严格。
  因为「打日志」在自己看来是「留证据」,不是「泄露」。而且它比写进配置文件更隐蔽——
  配置文件会被审查,日志不会;配置文件只在自己机器上,日志会进集中收集。
  判据很简单:钩子里凡是出现带 KEY、TOKEN、SECRET 字样的变量,一律当泄露处理。

  ④ 六条之间的关系
  --------------------------------------------------------------------
  前三条是「别让它做不该做的」,后三条是「别让东西流出去」。
  两组要一起做:只做前三组,它不越界但会泄密;只做后三条,东西不漏但它能乱来。
  这也正是 8.8 节那四道防线的思路——单条都拦不住,叠起来才有纵深。

  ⑤ 查配置这件事要自动化
  --------------------------------------------------------------------
  手查一定会漏,因为六条散在四个文件里。写成脚本,每次改配置跑一遍。
  这个脚本本身就是个 Hooks——提交前跑一次,比靠记忆可靠。
  ! 六条是这一课的归纳,字段名以各家实际配置为准;判据是「能机器检查」,不是「写得像」。

①六条落到字段:权限模式不是全放行、允许清单里没有裸命令、忽略清单覆盖密钥与数据目录、 钩子不打密钥、MCP 固定版本、密钥走环境变量。 ②三份过 1、4、5 条,没有满分。A 那条是「恰好没事」——钩子只有一句 echo,改一次就漏。 ③最严格那份栽在第四条:写了一行把密钥打进审计日志的命令。 它比写进配置文件更隐蔽——配置文件会被审查,日志不会。 ④前三条管「别做不该做的」,后三条管「别让东西流出去」,两组要一起做。

30 秒实验

  1. 把 C 的钩子改成只记「用了哪个密钥的代号」,重跑一遍。它现在过几条?
  2. 给 B 的忽略清单补上数据目录,重跑一遍。它和 C 的差距还剩几条?差距在哪一条上?
  3. 自己写一份配置,目标六条全过,重跑一遍。哪一条最难做到「既安全又不别扭」?

常见误区

  1. 开了全部放行模式。后面所有拦截都失效,等于没设防。
  2. 允许清单里留裸命令。等于把整台机器交出去,限定参数才是有意义的授权。
  3. 忽略清单只写密钥文件,不写数据目录。业务数据泄出去,后果一样。
  4. 钩子里打完整密钥。日志留得久、看的人多,比配置文件更危险。
  5. 用即时拉取的方式装 MCP。装到的是什么版本,自己也不知道。
自测三问(点开对答案) 1. 六条安全准则分别落到哪个字段? —— 权限模式、允许清单、忽略清单、钩子、MCP 来源、密钥。六条都能机器检查。 2. 哪一条最容易漏,为什么? —— 钩子里打密钥。它看起来是「留证据」不是「泄露」,而且日志比配置文件藏得更深。 3. 六条为什么分两组? —— 前三条管「别做不该做的」,后三条管「别让东西流出去」。只做一组,另一组就是缺口。

守住底线之后,下一节对付规模:在有限窗口里驾驭一个大仓库。

相关笔记