问题描述
Android 端使用内置的 Google 登录模块,登录成功后返回的数据里只有 openid 和 unionid,没有 id_token、access_token 或授权码。
服务端要确认“这次登录确实是该 Google 账号本人发起的”,必须拿到 Google 签发的 ID token 去核验。只有 openid 的话,任何人只要知道某个用户的 openid 就能伪造登录请求,存在账号冒用风险。目前 Android 端无法用内置模块实现安全的 Google 登录。
同一份代码在 iOS 端可以拿到能通过服务端核验的令牌,只有 Android 端缺失。
实际造成的安全问题
这个缺失已经在我们的线上环境造成了安全事故,过程如下。
- 客户端只能提交 openid:Android 端拿不到任何令牌,登录时只能把 openid 发给服务端,作为“这个用户已通过 Google 登录”的依据。
- 服务端被迫信任 openid:Android 端没有可核验的凭据,服务端只能为它保留一条“只凭 openid 就放行”的兼容路径,否则所有 Android 用户都无法用 Google 登录。
- openid 不是秘密:它是 Google 账号的固定标识,不会过期、不会变化,也不是只有用户本人才知道。它会出现在客户端日志、抓包数据和其他接入了 Google 登录的应用里。
- 攻击方式:攻击者不需要打开 App,也不需要经过 Google 授权。直接向登录接口发送一条请求,带上目标用户的 openid,服务端就会当作该用户登录成功并签发登录态。同样的方式也可以用任意编造的 openid 批量注册账号。
- 后果:已绑定 Google 登录的账号可以被他人冒用,攻击者登录后拥有该账号的全部权限。
问题的关键在于:服务端无法区分“真正通过 Google 授权的 Android 用户”和“直接伪造请求的攻击者”,因为两者提交的内容完全一样,都只有 openid。只要 Android 端拿不到 Google 签发的令牌,这条不安全的路径就无法关闭。
我们目前的处理是服务端停止接受只有 openid 的请求,同时自行编写原生插件获取 ID token。代价是所有旧版本 Android 用户在升级前都无法使用 Google 登录。
1 个回复
Ask小助手 - Ask社区AI助手
感谢这份 bug 反馈,整体质量很高。下面以官方评审视角,从反馈完整性和问题成立性两方面进行说明。
一、反馈完整性评审
二、bug 是否成立
结论:该问题成立,属于内置 Google 登录模块在 Android 端的已知能力差异,不是误报。依据如下:
三、替代方案建议
在官方内置模块补齐该能力之前,可参考以下方案:
四、文档与产品建议
您提出的三点希望(Android 端支持配置 Web client id、authResult 返回 id_token 且字段名与 iOS 对齐、文档补充返回字段说明及平台差异)均合理,尤其是文档目前确实未列出 Google 登录 authResult 的任何返回字段,这一点会随本次评审一并反馈。
如需持续跟进该问题,建议在 ask 社区 相关帖子下补充您的测试信息(HBuilderX 5.34、Android 16、vivo V2608A),以便官方汇总各版本复现情况。
要回复问题请先登录或注册
公告
更多>相关问题