使用Lambda授权器时 信任Cognito accessToken执行CRUD是否安全
结论
配置正确的前提下这个模式是安全的,但你贴的示例代码存在几个容易引发越权的隐患,不能直接上线用。
核心信任逻辑
Lambda授权器本质是API Gateway层的统一鉴权入口,正常的请求流转逻辑是:
- 用户携带Authorization头请求API接口
- API Gateway拦截请求,先把鉴权相关信息传给配置好的Lambda授权器
- 授权器完成token验签、有效期校验、权限匹配,校验通过才会返回允许访问的IAM策略,同时可以把解析好的用户标识(比如username)注入到授权上下文中
- 只有授权器放行的请求,才会被API Gateway转发到业务Lambda
这个流程里,授权器和API Gateway之间传递的授权上下文用户是无法篡改的,这部分内容是完全可信的。
你当前代码的风险点
示例代码没有用到授权器传递的可信上下文,反而直接从原始请求头取token、用无验签的jwt_decode解析后拿username,这步存在明确风险,常见出问题的场景包括:
- 授权器逻辑存在漏洞:比如没校验JWT签名、没校验token过期时间、权限匹配逻辑写错,放伪造的token过来到业务层,裸解token不做二次校验就会直接被越权
- 授权器缓存配置错误:比如没把Authorization头作为缓存键,导致A用户的鉴权结果被缓存后,B用户不带有效token也能复用缓存结果访问接口
- Lambda资源策略配置错误:如果业务Lambda没有限制仅允许API Gateway调用,攻击者可以绕过API Gateway直接调用Lambda,传入伪造的Authorization头,裸解token就会完全信任伪造的username
- 权限兜底缺失:如果业务Lambda持有DynamoDB全表读写权限,一旦代码里的查询条件因为bug失效,就可能泄露全表用户数据
安全的实现方式
- 优先从授权上下文取用户信息,不要自己解析原始请求头的token:校验通过的请求里,用户信息会放在
event.requestContext.authorizer字段下,这部分内容由授权器注入,用户无法篡改,是可信来源 - 如果确实需要自己解析token,必须使用带签名校验的JWT解析方法,不要用无验签的解码方法:解析时要同步校验签名合法性、token有效期、签发方、受众字段,确认是合法签发的token再取claim值
- 给业务Lambda配置最小权限的DynamoDB IAM角色,加细粒度权限限制:比如通过IAM条件限制Lambda只能查询、修改userName和当前调用用户匹配的记录,就算代码层出bug也不会出现跨用户越权
- 检查授权器缓存配置,确保鉴权结果和用户token一一绑定,避免缓存复用导致的越权
修正后的参考代码:
// 从授权器传递的可信上下文中取用户信息,不需要自己解码原始token const userName = event.requestContext.authorizer.claims.username; let params = { TableName: "myTable", IndexName: 'userName-gsi', KeyConditionExpression: 'userName = :userName', ExpressionAttributeValues: { ':userName': userName, }, Limit: 1, }; let data = await dynamodb.query(params).promise(); return { statusCode: 200, headers: utils.getResponseHeaderApplicantifyCors(), body: JSON.stringify(data.Items[0]), };
内容的提问来源于stack exchange,提问作者JustANoob
相关产品推荐
相关产品推荐

