01 · 函数认证授权双闸口模型
函数安全的第一性问题是授权。与虚拟机"登录即一切"不同,函数存在两道相互独立的授权闸口,任何一道失守都构成完整攻击路径:
- 闸口一:调用授权(Who can invoke)——决定哪些主体可以触发函数。AWS侧的机制包括IAM签名请求(SigV4)、函数资源策略(Resource-based Policy)、函数URL的AuthType配置(NONE / IAM),以及API网关层的授权器(Cognito JWT授权器、Lambda授权器、IAM授权);Azure侧默认使用Function Keys(主机密钥/函数密钥),官方文档明确推荐迁移至Microsoft Entra ID认证;GCP侧通过IAM成员绑定(如roles/run.invoker);国内云以RAM策略与触发器鉴权为主。
- 闸口二:执行授权(What the function can do)——决定函数代码能访问哪些云资源。AWS使用执行角色(Execution Role)+ IAM策略;Azure使用托管标识(Managed Identity,分系统分配与用户分配);GCP使用服务账号(Service Account);阿里云函数计算使用服务角色(RAM Role)。
最常见的事故模式:调用侧配置严谨(网关有认证),但函数被赋予通配符执行角色——攻击者一旦找到任一调用入口(包括绕过网关的事件源),即可借函数的高权限读取全部数据;反之,执行角色收紧但资源策略Principal:*公开,则任何匿名者均可触发函数逻辑。两道闸口必须分别设计、分别审计,不存在"一侧安全则另一侧可放松"的推论。
1.1 跨平台身份与授权机制对照
| 平台 | 调用侧机制 | 执行侧身份 | 密钥托管服务 |
|---|---|---|---|
| AWS Lambda | IAM签名调用 / 资源策略 / 函数URL(IAM或NONE)/ API网关授权器 | Execution Role(IAM角色,平台自动注入短期凭证) | Secrets Manager / Systems Manager Parameter Store(KMS加密) |
| Azure Functions | Function Keys(默认,官方推荐迁移)/ Microsoft Entra ID认证 | Managed Identity(系统/用户分配) | Azure Key Vault |
| GCP Cloud Run / Functions | IAM成员绑定(roles/run.invoker等)/ API Gateway + Firebase Auth | Service Account(建议一服务一账号) | Secret Manager |
| Cloudflare Workers | 无默认公网入口,经Cloudflare路由与Access策略控制 | 绑定式API令牌 / 服务绑定(Service Bindings)最小权限 | Workers Secrets存储 / 第三方密钥管理 |
| 阿里云函数计算 | RAM签名调用 / HTTP触发器鉴权配置 / 事件触发源授权 | 服务角色(RAM Role,按服务维度配置) | KMS / 凭据管家类托管服务 |
| 腾讯云SCF | 触发方式鉴权(API网关密钥、CAM策略)/ 函数级访问管理 | 运行角色(CAM角色) | Secrets Manager(KMS加密) |
02 · 执行角色最小权限工程
2.1 反模式清单
| 编号 | 反模式 | 风险 | 纠正措施 |
|---|---|---|---|
| A1 | 多函数共享一个执行角色 | 任一函数被注入或逻辑缺陷即获得全部函数所需权限的并集 | 一函数一角色;同业务域函数按数据敏感度拆分 |
| A2 | 通配符权限(*:*或service:*) | 权限探测后直达管理面(iam:*可创建新密钥持久化) | 按资源ARN精确授权;管理类权限默认拒绝 |
| A3 | 角色跨环境复用 | 测试环境函数可触达生产数据 | 开发/预发/生产分账号或分角色,互不信任 |
| A4 | 权限只加不减 | 角色随需求堆积成事实上的管理员 | 定期权限分析:AWS IAM Access Analyzer未使用访问调查发现未用权限后收敛 |
| A5 | 角色可被其他账户AssumeRole | 跨账户信任未加条件约束,外部账户横向进入 | 信任策略限定账户ID并施加ExternalId条件(官方最佳实践) |
2.2 最小权限策略示例(教学示意)
示例:一个仅被允许读取指定S3桶对象、写入指定DynamoDB表的处理函数执行角色策略(AWS IAM JSON,教学示例,非可直接部署模板):
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ReadSpecificBucketOnly",
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:GetObjectVersion"],
"Resource": "arn:aws:s3:::example-ingress-bucket/*"
},
{
"Sid": "WriteSpecificTableOnly",
"Effect": "Allow",
"Action": ["dynamodb:PutItem", "dynamodb:UpdateItem"],
"Resource": "arn:aws:dynamodb:us-east-1:123456789012:table/processed-records"
}
]
}该示例体现三个原则:动作最小集(只读所需两个S3动作)、资源精确到ARN(不含通配符)、无管理面权限(不含iam/kms/organizations类动作)。
2.3 权限治理的持续化
- 权限边界(Permissions Boundary):为函数角色附加边界策略,即使开发者后续附加策略也无法越界(AWS官方机制)。
- 未使用权限回收:IAM Access Analyzer的未使用访问分析可枚举角色在分析期内未调用的权限,支撑"先收紧、误伤再放行"的收敛流程。
- 变更审计:AttachRolePolicy / PutRolePolicy / CreatePolicyVersion等事件纳入告警(第7页检测场景)。
03 · 凭证治理:从长期密钥到短期身份
3.1 函数内凭证的三种形态与风险序
| 凭证形态 | 机制 | 风险与治理要求 |
|---|---|---|
| 执行角色临时凭证 | 平台自动注入执行环境(如Lambda经凭证提供程序按小时级轮换的STS临时凭证,官方文档可查) | 无需人工管理,但函数出站SSRF或代码漏洞可将其外泄——出站网络控制是必要补偿 |
| 长期访问密钥(AK/SK) | 环境变量或代码内硬编码的长期IAM用户密钥 | 应逐步消灭:泄露即持久入口;改用角色或OIDC联邦;存量依赖须配使用告警与季度轮换 |
| 第三方API密钥 | 支付、短信、Webhook验签等外部服务密钥,存于环境变量或Secrets Manager | 泄露可被直接消费产生账单;须托管化、分函数隔离、支持快速吊销 |
3.2 CI/CD部署身份的OIDC联邦
函数部署流水线使用长期AK是凭证泄露的重灾区(Denonia的部署途径推测即为凭证泄露)。现代实践是OIDC联邦:GitHub Actions、GitLab CI、Azure DevOps等CI系统以平台OIDC身份令牌换取云角色临时凭证(如GitHub Actions经AssumeRoleWithWebIdentity对接AWS,官方文档可查),流水线全程无长期密钥;AssumeRole临时凭证有效期可在15分钟至12小时间配置(默认1小时)。这一机制同时带来精细授权可能——可按仓库、分支、环境限定可Assume的角色(第6页流水线专项)。
3.3 出站面的凭证防外泄
- 函数默认可访问互联网——对持有高价值数据的函数,出站目的地应经NAT网关白名单或VPC终端节点收敛(第5页)。
- 禁用对云元数据端点与内部控制面的不必要访问;自建服务若暴露内部凭证端点,应视同生产机密面管理。
- 在代码评审清单中加入"禁止将凭证写入日志/异常消息/响应体"(SAS-10:不当错误处理常与凭证回显伴生)。
04 · 密钥与令牌管理基线
4.1 环境变量≠密钥管理
Lambda环境变量在静态存储时默认使用AWS托管KMS密钥加密(官方文档明确该行为,可切换为客户管理密钥以获得密钥使用审计),这解决了"静态加密"却不解决"运行时暴露":任何具备函数读取权限的角色(GetFunction / DescribeFunctionConfiguration)均可获取环境变量明文;函数异常栈、调试日志与配置导出也常以明文形式携带环境变量。结论:低敏感度配置可放环境变量;高价值密钥(数据库口令、第三方支付密钥、Webhook签名密钥)必须托管于Secrets Manager / Key Vault / Secret Manager类服务。
4.2 托管密钥访问的函数侧模式
| 模式 | 说明 | 适用与注意 |
|---|---|---|
| 调用时获取 + 进程内缓存 | 函数初始化阶段拉取密钥并缓存于执行环境内存,后续调用复用 | 减少密钥服务调用次数;缓存周期须短于密钥轮换周期 |
| 平台扩展缓存 | 如AWS Parameters and Secrets Lambda Extension(官方扩展),本地代理缓存参数与密钥 | 官方维护的缓存层;仍须为扩展配置最小IAM权限 |
| 动态轮换兼容 | Secrets Manager自动轮换(数据库类密钥)配合缓存过期窗口设计 | 轮换事件(CloudTrail)应触发函数侧缓存刷新或环境重建 |
| 第三方密钥管理 | HashiCorp Vault动态密钥、短期数据库凭据模式 | 引入外部依赖与可用性考量;函数冷启动时延增加 |
4.3 Webhook验签基线
接收第三方回调的函数必须校验事件真实性:使用提供方签名字段(如HMAC-SHA256)对原始请求体重算摘要并比对,验签失败即拒绝;严禁以"来源IP白名单"作为唯一防线(IP可伪造或经代理变化,只能作为辅助信号)。验签密钥按提供方分函数隔离存放,泄露时可单点吊销。
05 · 常见认证失效模式
| 编号 | 失效模式 | 机理与后果 | 基线处置 |
|---|---|---|---|
| F1 | JWT校验缺失或弱实现 | 仅验签名不验iss/aud/exp,或自行实现校验逻辑——token伪造/跨服务重放 | 使用平台授权器或经审计的库;强制校验签发者、受众与有效期 |
| F2 | 授权器结果缓存滥用 | API Gateway Lambda授权器的结果缓存TTL内不感知令牌吊销——已撤权用户继续调用 | 敏感场景缩短TTL或禁用缓存;吊销事件触发主动失效 |
| F3 | Function Keys长期不轮换 | Azure Functions默认密钥机制硬编码于客户端分发,泄露面大且难以追溯 | 按官方推荐迁移Entra ID;过渡期密钥分函数粒度并定期轮换 |
| F4 | 资源策略Principal:* | 任何匿名主体可Invoke函数——公网匿名计算入口 | 资源策略显式列举账户/服务主体;AWS Config托管规则lambda-function-public-access-prohibited可持续审计 |
| F5 | CORS通配配凭据 | Access-Control-Allow-Origin:*与Allow-Credentials:true组合使任意站点可携带凭据调用 | 精确Origin白名单;凭据请求严格收窄 |
| F6 | 跨账户AssumeRole缺ExternalId | 第三方可被诱导代入信任你的角色的场景(混淆代理人) | 信任策略强制ExternalId条件并限定来源账户(官方最佳实践) |
| F7 | 事件源侧无独立鉴权 | SQS/SNS/S3侧策略公开,攻击者绕过网关直投恶意事件 | 事件源资源策略最小化;存储桶默认私有(第5页) |
本节参考来源(第3页)
以下均为真实可查的权威来源,用于支撑本页事实性表述。
AWS Lambda权限官方文档(执行角色与资源策略、资源策略公网调用风险):Lambda permissions。
AWS API Gateway授权器官方文档(JWT/Lambda/IAM授权器及结果缓存行为):Controlling access to API。
Microsoft Learn:Azure Functions安全概念(Function Keys默认机制与Entra ID推荐):Azure Functions security concepts。
Microsoft Learn:托管标识概述(Managed Identity):Managed identities overview。
Google Cloud:服务账号(Service Account)官方文档:cloud.google.com/iam/docs/service-accounts。
GitHub Docs:在Amazon Web Services中配置OpenID Connect(CI/CD联邦凭证):Configuring OpenID Connect in AWS。
AWS IAM官方文档(AssumeRole临时凭证有效期15分钟—12小时、ExternalId最佳实践、Access Analyzer未使用访问分析):IAM Access Analyzer。
AWS官方文档:Parameters and Secrets Lambda Extension(函数侧密钥缓存扩展):Parameter Store Lambda extension;AWS Config托管规则lambda-function-public-access-prohibited:AWS Config managed rules。