如何保护从 OAuth 受保护资源中提取数据的 Android 应用程序
Posted
技术标签:
【中文标题】如何保护从 OAuth 受保护资源中提取数据的 Android 应用程序【英文标题】:How to secure Android App that pulls data from OAuth protected resource 【发布时间】:2012-08-13 02:49:33 【问题描述】:我的公司正在构建一个 RESTful API,它将返回中等敏感信息(即财务信息,但不包括帐号)。我可以控制 RESTful API 代码/服务器,并且正在构建 android 应用程序。我已经将 API 设置为使用 OAuth 2 和授权代码授予流程(带有客户端 ID 和密码),并且我自动批准用户而无需他们批准客户端,因为我们同时拥有客户端和提供者。我们将 CAS 用于 SSO,当用户登录以检索令牌时,我将其用于授权服务器作为 OAuth 2 过程的一部分。
我正在考虑各种方法来保护 Android 应用上的数据。我得出的结论是,在设备上存储客户端 ID 和机密肯定不会发生,但我认为存储身份验证令牌可能会起作用,因为它只会对个人用户造成风险(而且真的只有当他们碰巧有有根电话)。
这是我想到的两个选项。它们都要求我拥有一种受 CAS 保护的代理服务器,与 API 服务器共舞,并返回身份验证令牌。这消除了在应用程序代码中存储客户端 ID 和密码的需要。
这是我想出的:
1) 要求用户在每次启动应用程序时输入密码才能访问数据。这绝对是最万无一失的方法。如果这样做了,为了方便起见,我可能想保存用户 ID,但在这种情况下,不能使用 CAS 登录(因为它是基于 Web 的)。我也许可以在后端使用无头浏览器将用户登录到 CAS 并根据他们在 Android 表单中输入的内容检索令牌,但这似乎很棘手。保存用户 ID 类似于 Chase 应用程序所做的(如果您碰巧使用这个) - 它会保存用户 ID,但不会在会话之间保存您的密码。
2) 将身份验证令牌存储在 Android 设备上。这有点不安全,但几乎是万无一失的。用户第一次启动应用时,打开网页到返回token的代理服务器的CAS登录(类似https://developers.google.com/accounts/docs/MobileApps)。在用户登录并将令牌返回给应用程序后,对其进行加密并将其私有存储给应用程序。此外,使用 ProGuard 混淆代码,使加密算法更难逆向工程。我也可以在令牌刷新中工作,但我认为这更像是一种虚假的安全感。
3) 不要使用 CAS,而是想出另一种方法来获取服务的身份验证令牌。
关于其他人如何实现类似场景(如果已经完成)的任何建议?
谢谢。
【问题讨论】:
有点难以理解和回答您的问题,因为它涵盖了相当广泛的范围,但也涉及到不同方面的详细信息。不过我会在一分钟内试一试;) 【参考方案1】:开发 OAuth 等标准的原因是,并非每个人都必须一次又一次地重新考虑相同的攻击向量。因此,大多数情况下,最好的选择是坚持现有的东西,而不是自己烘焙。
无法秘密存储数据的客户端的第一个问题是用户的数据可能会被某些攻击者访问。由于在技术上无法阻止这种情况(代码混淆不会帮助您对抗专家攻击者),OAuth 2 typically expires 中的 访问令牌 在短时间内不会给攻击者完整访问(受范围限制)。当然,您不应该在这样的设备上存储任何 刷新令牌。
第二个问题是client impersonation。攻击者可以窃取您的客户端密码并在他自己的(可能是恶意的)应用程序中访问您的 API。用户仍然必须自己登录。那里的 OAuth 草案要求服务器尽其所能防止这种情况发生,但这真的很难。
授权服务器必须尽可能对客户端进行身份验证。如果授权服务器由于客户端的性质而无法对客户端进行身份验证,则授权服务器必须要求注册任何用于接收授权响应的重定向 URI,并且应该使用其他方式来保护资源所有者免受此类潜在恶意客户端的侵害。例如,授权服务器可以让资源所有者帮助识别客户端及其来源。
我认为 Google 是第一个尝试通过检查应用程序签名来验证此类设备上的客户端的另一种方法,但它们还没有准备好迎接黄金时段。如果您想更深入地了解该方法,请参阅my answer here。
目前,您最好的选择是继续使用 OAuth 方式,即拥有 访问令牌、客户端 ID 和 客户端密码 (在设备上使用授权码授予流程),并配置您的服务器以进行额外检查。如果您觉得混淆这些值更安全,那就去做吧,但始终认为这些值是公开可用的。
【讨论】:
以上是关于如何保护从 OAuth 受保护资源中提取数据的 Android 应用程序的主要内容,如果未能解决你的问题,请参考以下文章