是什么阻止其他应用窃取我的Google OAuth客户端ID?

时间:2018-12-04 22:00:13

标签: android google-oauth appauth

我创建了一个使用AppAuth通过Google OAuth进行身份验证的Android应用。在Google Cloud Platform Console中,我为我的应用程序创建了Android OAuth 2.0客户端ID,并提供了应用程序包名称和签名证书指纹。一切正常。

我想确认只有我的应用可以使用该客户端ID。因此,我使用不同的程序包名称创建了另一个应用程序,并使用不同的签名证书对其进行了签名。使用相同的客户端ID,我仍然可以通过Google进行身份验证并访问API。我认为情况并非如此。我正在查看AppAuth的源代码,看起来好像在身份验证流程中从未使用过应用程序签名或程序包名称。它当然使用PKCE,但我希望还会有更多事情发生。

因此,如果我可以毫不费力地窃取自己的客户端ID,该如何阻止其他人从我的APK中提取客户端ID并将其用于身份验证?根据包名,我很容易确定用于重定向URI的自定义方案。因此,胭脂应用程序可以将AppAuth配置为使用类似的重定向URI并捕获授权结果。而且由于PKCE仅用于验证授权请求和代码交换来自同一位置,因此rouge应用程序会同时执行这两种操作,因此那里也没有真正的保护。

我可以将客户端ID类型切换为Web或“其他”,但这将要求我使用客户端密码,如果将其嵌入到应用程序中,这也是不安全的。

我遗漏了某些东西吗?还是Google OAuth完全按照预期的方式工作?

3 个答案:

答案 0 :(得分:1)

对于客户端Google OAuth 2,您的客户端ID并不重要。客户端执行OAuth流,并且客户端接收OAuth令牌。魔术在于客户必须授权Google。任何人都可以窃取您的客户ID,但是他们无法执行任何操作。作为OAuth生命周期的一部分,您应该验证OAuth令牌。您的后端不应盲目接受客户的任何东西-或不受您绝对控制的任何地方。

您的客户ID并非机密信息,您可以在代码中将其明示。

必须保留的客户端机密。客户端身份验证中不涉及客户端机密。客户端机密用于您的后端服务器上。

我认为您在混淆该过程。当客户端应用程序(您的应用程序,网络浏览器等)通过Google帐户进行身份验证时,您的应用程序未获得授权。客户端被授权。客户应该对他们访问哪些网站(或应用程序)并使用其Google登录信息做出正确的判断。客户端可以使用其令牌执行的唯一操作是访问其自己的数据(Google云端硬盘,Gmail等)。如果您的后端服务器正在接受客户端的OAuth令牌来管理访问,则您有责任验证该令牌及其在系统上的期望用法以及该令牌的授权人。

一个更好的选择是在后端(例如,您的Web服务器)上执行身份验证和授权。然后,您可以实施Google OAuth重定向,以将OAuth令牌发送到您的服务器。您受到保护,因为仅授权来源(例如您的域名)和授权重定向URI(Web服务器上的端点)可以参与身份验证过程。然后,您将令牌存储在客户端会话中,在必要时进行续订,根据需要添加授权范围,等等。

我经常使用这两种方法(客户端,服务器端),并且都很好用。

答案 1 :(得分:1)

只有原生应用和单页应用没有客户端机密,因此它们必须切换到其他应用。这里必要的保护是重定向 URL。对于 Web 托管的单页应用程序,无论如何设置,这都不是问题。它们完全托管在此重定向 URL 上。对于本机应用程序,必须完成另一步骤。 Android 和 iOS 允许使用“应用程序声明的 https URL 重定向”。这会将 https URL 直接绑定到应用程序。可以请求这些声明的 URL 重定向,然后必须通过特定地址上的签名进行确认:https://developer.android.com/training/app-links/verify-site-associations

使用这种方法,为了使用外部client_id,https重定向必须被假客户端拦截(只有root环境,大多数手机都没有)。 通过大量的努力,欺诈者可以使用相同的 client_id 运行另一个前端。 在这样的用例中:

  • 使用 API 会产生成本(例如自己的 API)
  • 在前端投放广告产生收入

这是重新思考架构的理由。

在您描述的用例中,这不是问题,因为您不拥有 API 资源。资源所有者,即已登录的 GCP 用户,必须为其 GCP 使用付费。在公共客户端上,您不能让客户端本身向授权服务器进行身份验证(仅对用户进行身份验证)。

答案 2 :(得分:0)

我想在此处添加与Financial Grade APIs中针对移动应用的建议有关的后记,以使用声明的HTTPS方案接收登录响应。这会将客户端ID限制为带有数字签名的应用程序使用。

有关更多信息,请参阅我的博客文章,其中描述了任何人都可以运行的代码示例: