篡改AWSCognito用户池属性的危险游戏

admin 2026-05-20 06:08:31 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文揭示了AWSCognito用户池属性默认开放读写权限的安全风险,通过真实案例展示攻击者如何篡改自定义属性custom:Xplatformuser_id劫持第三方平台数据。关键发现包括:CognitoAppIntegration默认允许用户通过AccessToken修改所有属性,若后端将此属性用于核心逻辑(如数据查询)即形成漏洞。修复方案包括关闭非必要属性的写权限、使用Terraform显式配置读写属性实现最小权限,并推荐配套漏洞实验室进行实践验证。 综合评分: 85 文章分类: 漏洞分析,云安全,WEB安全,安全建设,应用安全


cover_image

篡改 AWS Cognito 用户池属性的危险游戏

幻泉之洲

2026年5月19日 09:50 北京

在小说阅读器读本章

去阅读

AWS Cognito 的用户属性默认对认证用户开放读写权限。如果后端把这些属性用在了关键判断上,攻击者只要拿到自己的 JWT 就能直接改写。本文还原了一个真实案例——通过篡改一个自定义属性,攻击者劫持了别人的第三方平台数据。文章会讲清楚这个坑出在哪,以及怎么修。

先花一分钟回顾上期谜题。上回那个数据导入挑战[1],目标是读到一个内部 S3 桶里的内容。前端应用用这个桶存 Logo,桶名通过 /variable 接口返回给客户端。

服务端会返回类似这样的东西:

“data-internal-private-20220705153355922300000001”

好,规则很清楚了。用数据导入功能去探测这个桶里的对象:

从内部 S3 桶捞出数据

然后在 Data Gallery 里就能看到 keys.txtdummy.txt,这些就是藏在内部桶里的文件。这个思路在我们马上要讲的本期案例里还能看到影子。

AWS Cognito 的默认设计有多开放

Cognito 是 AWS 给应用准备的认证套件,管注册、登录、访问控制那一整套。它把用户资料存在一个叫“用户池”的目录里。每个用户有一堆属性,比如邮箱、手机号,还能加自定义字段。

两个核心组件:

  • 用户池:管注册登录和用户属性。
  • 身份池:给用户发临时 AWS 凭据,访问 S3、DynamoDB 这些。

应用通过 App Client 来调用户池的操作 API。一个用户池可以有多个 App Client,一般每个平台一个。认证方式有两种:客户端直接把用户名密码发给 Cognito 换 JWT,或者服务端用 AdminInitiateAuth,后端拿自己的 AWS 凭据去换。

最终用户手里都会拿到一个 JWT。里面大概长这样:

{ “sub”: “cf9..[REDACTED]”, “device_key”: “us-east-1_ab..[REDACTED]”, “iss”: “https://cognito-idp.us-east-1.amazonaws.com/us-east-1_..[REDACTED]”, “client_id”: “9..[REDACTED]”, “origin_jti”: “ab..[REDACTED]”, “event_id”: “d..[REDACTED]”, “token_use”: “access”, “scope”: “aws.cognito.signin.user.admin”, “auth_time”: [REDACTED], “exp”: [REDACTED], “iat”: [REDACTED], “jti”: “3b..[REDACTED]”, “username”: “[REDACTED]” }

这个 Access Token 能调一堆用户池接口,官方列表在这里:https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_Operations.html。只要你看到 API 请求参数里有 "AccessToken": "string",持有上面那个 JWT 的人就能改自己账户的对应内容。

一个属性,两个账户

我们碰到的是一个 Web 平台,接 AWS Cognito 管用户,同时又把每个用户映射到一个第三方平台 X_platform 上。用户在平台里关联自己的 X_platform 账号,平台拿关联后的数据做后续处理。

用 CLI 拉一下当前用户的属性:

$ aws cognito-idp get-user –region us-east-1 –access-token eyJra..[REDACTED SESSION JWT]

返回:

{ “Username”: “[REDACTED]”, “UserAttributes”: [ { “Name”: “sub”, “Value”: “cf915…[REDACTED]” }, { “Name”: “email_verified”, “Value”: “true” }, { “Name”: “name”, “Value”: “[REDACTED]” }, { “Name”: “custom:X_platform_user_id”, “Value”: “[REDACTED ID]” }, { “Name”: “email”, “Value”: “[REDACTED]” } ] }

看到那个 custom:X_platform_user_id 没有?直觉告诉我这玩意儿不简单。果然,后端拿它当主键,去内部数据库里查对应的 refresh_token,然后用这个 token 去 X_platform 拉数据展示给你看。

这时候想法很简单:能不能改成别人的 ID?试一下:

$ aws –region us-east-1 cognito-idp update-user-attributes –user-attributes “Name=custom:X_platform_user_id,Value=[ANOTHER REDACTED ID]” –access-token eyJra..[REDACTED SESSION JWT]

改完刷新页面,另一个用户的数据直接流进我的账户里了。平台把这属性当成不可变的了,毫无防备。

为什么会这样

根子在新版 App Integration 的默认权限上。看图:

看到了吗?“Attribute read and write permissions”这一栏,默认是所有属性都可读写。也就是说,任何拿到 Access Token 的用户都能直接用 AWS CLI 改自己池子里的属性值。

设计本身不是漏洞,但一旦后端把这些可编辑的属性放进核心逻辑,漏洞就来了。说白了,如果平台信任了一个用户自己可以改的值,那就等于把钥匙交给了用户。这个案例里,custom:X_platform_user_id 就是一个绝佳的例子。

审计该看什么

开发和安全人员检查基于 Cognito 的平台时,盯住这几个问题:

  • 用户池有哪些属性?
  • 哪些能用 JWT 通过 CLI 直接改?
  • 这些可编辑的属性里,有没有被后端用于权限判断、数据查询、或者其他关键流程的?
  • 它们具体怎么参与了业务逻辑?
  • 改掉某一个值会发生什么?

不要只盯权限表,要顺着数据流走。从属性赋值点一直追到它被消费的地方。

开发怎么修

最直接的办法:在 App Integration 里,把那些会参与后端逻辑的属性写权限关掉。只保留确实需要用户自行编辑的属性(比如头像、昵称),其他一概设为只读。

关了写权限后,用户用 Access Token 就改不了了。只有通过 Admin API(例如 admin-update-user-attributes,https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/admin-update-user-attributes.html)才能动,而调这个需要有后台 AWS 凭据。

如果你用基础设施即代码,别手动点控制台,直接在 Terraform 里声明好:

resource “aws_cognito_user_pool” “pool” {  name = “pool” }

resource “aws_cognito_user_pool_client” “client” {  name = “client”  user_pool_id = aws_cognito_user_pool.pool.id  read_attributes  = [“email”]  write_attributes = [“email”] }

这里的写法很关键:一旦你在 read_attributeswrite_attributes 里指定了哪怕一个属性,Cognito 就会忽略默认的全局读写策略,变成只显式放行指定的属性。没列出来的,读写全关。这样就能做到最小权限。

另外别忘了,邮箱和手机号可能存在未验证的情况。如果涉及这两个属性的写入,一定要设 RequireAttributesVerifiedBeforeUpdate 参数,不然用户可能刷一个未验证邮箱进去搞事。

自己搭个 Lab 玩玩

这个系列配套了一个用 Terraform 部署的漏洞实验室,覆盖了本文的场景:https://github.com/doyensec/cloudsec-tidbits/。拉下来部署一下,亲手改一次属性试试,比看十遍文章都管用。


参考:

  • AWS Cognito 用户池属性管理:https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-attributes.html
  • UpdateUserAttributes API:https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UpdateUserAttributes.html
  • Amazon Cognito 开发者指南:https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-dg.pdf
  • 邮箱和电话验证配置:https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-email-phone-verification.html

参考资料

[1] https://blog.doyensec.com/2022/10/18/cloudsectidbit-dataimport.html

[2] https://blog.doyensec.com/2023/01/24/tampering-unrestricted-user-attributes-aws-cognito.html


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:幻泉之洲 《篡改 AWS Cognito 用户池属性的危险游戏》

评论:0   参与:  0