一句话版本
安全事故里,最常见的放大器不是"漏洞有多深",而是"被偷走的那把钥匙能开多少扇门"。最小权限原则说:每个人、每个程序、每个 token,只拥有完成本职工作所需的最少权限。 落到工程上就是三件事:token 范围要窄、密钥不要明文躺在磁盘上、服务之间要隔离。这样即使某一处失守,损失也被限制在那一扇门之内。
全文分三层:
- 通俗理解:万能钥匙为什么危险
- 实际用处:Codecov、CircleCI、Uber、Badger DAO 等真实事件
- 原理与工程要点:窄权限 token、密钥存储、服务隔离、轮换
第一层:通俗理解
1.1 万能钥匙
一栋办公楼,保洁员只需要能开走廊和卫生间。如果图省事给了他一把万能钥匙,那么这把钥匙一旦丢失,整栋楼的保险柜、机房、档案室都暴露了。
软件世界里,"万能钥匙"随处可见:
- 一个云平台 API token,能改 DNS、改网站、改邮件转发、删数据库;
- 一台服务器上跑着十几个服务,全都用 root 身份运行;
- 一个
.env文件,里面放着所有服务的所有密码,明文存在开发者电脑上。
1.2 最小权限的含义
1975 年,Saltzer 和 Schroeder 在经典论文《计算机系统中的信息保护》里把它列为安全设计的基本原则之一:
每个程序、每个用户,只使用完成工作所需的最少权限。
它不能阻止钥匙被偷,但决定了钥匙被偷之后损失有多大。
第二层:实际用处
| 事件 | 经过 | 如果做到最小权限 |
|---|---|---|
| Codecov(2021) | 攻击者篡改了一个被大量 CI 流水线使用的上传脚本,脚本把 CI 环境变量(里面有各种云服务凭证)发了出去 | CI 环境里只放这一步必须的凭证,泄露面会小得多 |
| CircleCI(2023) | 一名工程师的电脑中了恶意软件,会话被盗,攻击者进而访问了客户存在平台上的密钥,平台要求所有客户轮换全部密钥 | 敏感凭证分级存放、短期有效 |
| Uber(2022) | 攻击者进入内网后,在一个网络共享里找到了硬编码管理员凭证的脚本,从而拿到大量内部系统的权限 | 凭证不写进脚本;管理员权限按需申请 |
| Badger DAO(2021) | 攻击者拿到一个 Cloudflare API 密钥,往 DeFi 前端注入恶意脚本,损失约 1.2 亿美元 | 部署 token 只能改特定站点,且有版本监控(见《Bybit事件与前端完整性》) |
Caloogy Wallet 也采用了最小权限原则管理部署凭证和服务。
第三层:原理与工程要点
3.1 token 要窄
现代云平台基本都支持细粒度权限。给每个用途单独建一个 token:
| 用途 | 应有的权限 | 不应有的权限 |
|---|---|---|
| 部署前端 | 只能更新某一个站点或脚本 | 改 DNS、改邮件、管理账号 |
| 监控 | 只读 | 任何写权限 |
| 紧急下线 | 只能摘掉某条路由 | 修改页面内容 |
再加上:设置过期时间;能限制来源 IP 就限制;token 名字写清楚用途,方便日后审计和吊销。
3.2 密钥不要明文躺在磁盘上
| 存法 | 风险 |
|---|---|
| 写进代码、提交到 Git | 最糟:仓库公开或被克隆就泄露,而且历史记录里永远删不干净 |
| 家目录里的明文文件 | 任何以你身份运行的程序(包括恶意的 npm 包、浏览器扩展)都能读 |
| 系统钥匙串(macOS Keychain、Windows 凭据管理器、Linux Secret Service) | 加密存储,读取时可能需要授权;用时才取出 |
| 专门的密钥管理服务(Vault、云 KMS、Secrets Manager) | 适合服务器:集中管理、审计、自动轮换 |
一个实用的小技巧:保存 token 时让脚本从剪贴板读取并直接写入钥匙串,token 不会出现在屏幕、终端历史或聊天记录里。
3.3 服务隔离
- 每个服务用独立的系统用户运行,而不是 root 或共用账号;
- 代码目录归 root、只读;数据目录只有本服务用户可读写(权限
0700/0600); - 每个服务有自己的配置文件和密钥文件,不共享一个大
.env; - 持有私钥、能动钱的服务,单独一台机器,不和其他服务混跑。
这样,一个服务被攻破,攻击者拿到的只是那个服务用户的权限,读不到隔壁的密钥。
3.4 被忽略的一环:开发者自己
很多供应链攻击的起点不是服务器,而是开发者的电脑(Bybit、CircleCI 都是)。开发者电脑上往往存着权限最大的凭证。对策:
- 云账号、代码托管、域名注册商一律开启强两步验证(最好是 passkey 或硬件密钥);
- 高权限操作用短期凭证,用完即失效;
- 部署工具锁定版本,不要每次运行都去下载"最新版"。
总结
| 层次 | 要点 |
|---|---|
| 原则 | 只给完成工作所需的最少权限;钥匙丢了损失也有限 |
| token | 一个用途一个 token;只读优先;设过期 |
| 存储 | 不进代码、不放明文文件;用钥匙串或 KMS |
| 隔离 | 独立系统用户、独立文件权限;动钱的服务独占机器 |