4、最小权限原则:为什么最小权限能防止滥用,如何实施
咱们聊点实在的。你琢磨琢磨,IAM 策略滥用是怎么发生的?十有八九是因为权限给得太大方了。给了一个 S3 的 FullAccess,结果整个桶被删光了;给了一个管理员权限,结果员工离职后数据被批量导走。说白了,滥用,往往始于“权限超标”。
我刚开始做云安全那会儿,也觉得“权限多点没事,省得麻烦”。直到有一次,一个开发小哥为了测试方便,把 Lambda 的执行角色绑上了 AdministratorAccess。结果函数被外部调用,攻击者直接拿这个角色把 RDS 的备份给删了。嗯,从那以后,我再也不敢讲“给大权限没事”这种话了。
最小权限为什么能防滥用?
最小权限,英文叫 Least Privilege。它的核心逻辑很简单:只给做某件事必需的最小权限,多一点都不给。
从安全角度讲,它切断了三条主要的滥用路径:
- 权限扩大路径——攻击者拿到一个高权限账户后,可以做更多事情;最小权限让攻击者“举手无措”。
- 误操作路径——开发者不小心执行了删除命令,但因为没权限,命令失败,数据保住。
- 横向移动路径——一个服务只能访问自己桶里的数据,无法跳到别人的桶里去。
你想想看,如果一个角色只能读自己桶里的对象,就算凭证泄露,攻击者能干什么?最多看看日志文件。这就是最小权限的“缩小攻击面”效果。
我的习惯:每次创建角色,我都会先问自己三个问题:
1. 这个角色必须访问哪些资源?
2. 必须执行哪些操作?
3. 在什么条件下可以执行?
答不上来的权限,一律不放行。
核心思路:拒绝优先,显式授权
很多团队的策略写得像“白名单”+“黑名单”混合体。其实正确的做法是:先拒绝所有,再显式放行需要的。IAM 默认就是隐式拒绝,所以你只需要把要允许的动作列清楚就行。
举个例子,一个负责读取 S3 日志的分析员,你给他这样的策略:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my-logs-bucket",
"arn:aws:s3:::my-logs-bucket/*"
]
}
]
}
看到了吗?没有 s3:PutObject,没有 s3:DeleteObject。就算他写代码时不小心调了删除接口,也会返回 AccessDenied。这就是最小权限的落地形态。
我曾经踩过的坑:给一个 Lambda 函数配了 s3:*,觉得“只限定了桶应该没问题”。结果函数被注入攻击,攻击者用 s3:PutObjectAcl 把桶公开了。各位,Action 一定要精确到最小粒度,别用通配符糊弄。
如何评估现有角色的权限
光说理论不行,你得有方法。我常用的评估手段有几种:
| 方法 | 适用场景 | 说明 |
|---|---|---|
| IAM Access Analyzer | 已有策略 | 自动分析策略,找出未使用的权限、隐式允许等问题 |
| CloudTrail + Athena 查询 | 运行中的工作负载 | 查找过去90天内实际调用的API,跟策略比对 |
| 手动审计 | 小团队/关键角色 | 逐条检查策略中的Action和Resource,剔除多余项 |
| 模拟策略(Simulate Principal Policy) | 测试新策略 | 在IAM控制台或CLI模拟执行,看哪些API会失败 |
说白了,不要相信你写的策略“已经够小了”。我见过太多策略里写着 s3:ListAllMyBuckets 但实际根本不需要——这个东西能枚举整个账号下的所有桶名,信息泄露风险很大。
权限收缩的实战技巧
怎么把一个大权限策略“瘦身”?我总结了几步,百试百灵:
- 先列出角色实际使用的API——从CloudTrail里导出最近30天的日志,统计出所有调用的Action。
- 生成最小策略——用
Access Analyzer的“生成策略”功能,基于你的API调用自动生成一个最小策略。 - 加上条件限制——比如限制只能在 VPC 内调用、只能访问指定标签的资源、必须使用 TLS 等。
- 替换通配符——把
Action: ["*"]换成列表,把Resource: ["*"]换成具体ARN。 - 测试、测试、再测试——先在非生产环境模拟执行,确认没有功能报错才切换。
硬性要求:生产角色不允许出现 "Action": "*" 或 "Resource": "*"。如果有,必须走例外审批流程,而且例外策略要附带到期自动删除的机制。
最小权限与临时权限提升
有些场景下,你确实需要临时扩大权限,比如运维排障、紧急数据恢复。这时候不是放弃最小权限,而是用“临时提升”来替代永久授权。
我的做法是:把临时提升封装成审批流。比如用 AWS Systems Manager 配合 IAM 角色自动切换,或者用 sts:AssumeRole 切换到高权限角色,并在 CloudTrail 中记录每次提升。员工完成任务后,角色自动到期或手动回收。
这样既满足了紧急需求,又保持了日常的最小权限。你想想看,是不是比直接给永久高权限好得多?
这张图展示了我推荐的实施闭环。从识别角色开始,到分析实际调用、生成最小策略、加条件、测试切换,最后定期审核并继续收缩。这是一个持续优化过程,别指望一次就能做到完美。
避坑指南
我曾经见过一个团队:他们严格遵循了最小权限,但没考虑“跨账号访问”。A 账号的角色对 B 账号的桶有s3:GetObject权限,但 B 账号的桶策略没限制,导致 A 账号的凭证泄露后,攻击者通过这个角色把 B 账号的桶也扫了一遍。所以记得:最小权限不仅管自己账号,还要管信任关系中的外部实体。
另外一个常见问题是权限膨胀。今天加一个权限,明天加一个权限,一年后角色权限比最初大了五六倍。所以我建议每个角色都贴上创建时间,每隔90天做一次权限复核,把没用到的一律删除。
我的个人习惯:用 aws iam get-service-last-accessed-details 这个 API,可以查出一个角色最近多久没用某个服务。超过90天没用的权限,我先在策略里注释掉(用 "Condition" 临时禁止),观察一周没问题再彻底删除。
说了这么多,你可能会觉得最小权限有点麻烦。没错,它确实比“一把梭”麻烦一些。但你想一下,一次数据泄露带来的损失,可能是一个运维团队半年的工作量。花一个小时把策略写精确,对比花几个星期救火,哪个更划算?答案很明显。