如何保护OAuth使用者的​​机密安全,以及在受到威胁时如何做出反应?


76

这个问题是关于尝试了解在Android等移动平台上实施oauth所涉及的安全风险。这里的假设是我们有一个Android应用程序,该用户程序在代码中嵌入了使用者密钥/秘密。

假设一个消费者的秘密已经被泄露,而黑客已经掌握了这个秘密,那么这将带来什么后果呢?

损害的消费者秘密假设
我是正确的,是说损害的消费者秘密本身不会影响用户的安全,也不会影响与用户进行交互的存储在启用OAuth的提供程序上的任何数据。数据本身不会受到破坏,黑客也无法检索。

黑客将需要持有有效的用户访问令牌,而这要难得多。

黑客如何处理受侵害的消费者秘密?
我也正确指出以下内容:

  • 黑客可以设置/发布模仿我的应用程序的应用程序。
  • 黑客可以吸引将要经过OAuth流程的用户,通过黑客的OAuth舞蹈(使用受害的用户密钥/秘密)检索访问令牌。
  • 用户可能会认为他正在处理我的应用程序,因为他会在授权过程中看到一个熟悉的名称(用户密钥)。
  • 当消费者通过黑客发出请求时,黑客可以轻松地拦截访问令牌,并且与消费者秘密结合在一起现在可以代表我对请求进行签名,以访问我的资源。

最终用户的影响
。在假设

  • 黑客使用我的消费者秘密设置了应用程序/站点
  • 我的一位用户被骗去授权访问该应用程序/站点

可能发生以下情况:

  • 最终用户可能会注意到发生了一些可疑的情况,并将恶意应用告知服务提供商(例如Google)
  • 然后,服务提供商可以撤消使用者密钥/秘密

OAuth使用者(我的应用程序)的影响:
我的应用程序(包含使用者的机密)将需要更新,否则所有我的客户将无法再授权我的应用程序代表他们的请求(因为我的使用者机密将不再有效)。

委派所有OAuth流量
尽管可以通过中间Web服务器委派许多OAuth交互(进行OAuth舞蹈并将访问令牌发送给用户),但也必须代理所有服务交互,作为使用者密钥/ secret是签署每个请求所必需的。这是将使用者密钥/秘密保存在移动应用程序外部并存储在中间Web服务器上更安全的位置的唯一方法吗?

替代
方案此代理有替代方案吗?是否可以将消费者秘密存储在中间Web服务器上,并且具有某种机制,使得Android应用程序(已在市场上发布并经过适当签名)可以对中间Web服务器发出安全请求,以获取消费者秘密并将其存储在应用内部?是否可以实施一种机制,使中间Web服务器“知道”这是一个要求获取用户机密的官方android应用程序,并且中间Web服务器将仅将用户机密分发给该特定android应用程序?

Answers:


53

摘要:我只是冒险,将秘密保存在客户端应用程序中。

代理服务器替代

可以合理缓解我在下面列出的问题并使代理工作的唯一方法是走整个9码-将用于处理第三方Web服务上的资源的所有业务逻辑移到您的代理服务器上,并且使客户端应用程序的哑终端具有丰富的UI。这样,恶意应用程序能够使代理代替其执行的唯一操作就是您的业务逻辑合法需要的操作。

但是,现在您遇到了必须解决可靠性和可伸缩性的一系列其他问题。

关于简单代理为何行不通的漫长讨论

有些人遇到问题时会想到“我知道,我将添加自己的代理服务器”,现在他们有两个问题。(对Jamie Zawinski表示歉意)

您的假设在很大程度上是正确的。一直到您开始考虑自己的服务器时,服务器是保留秘密并代理客户端应用程序的调用,还是尝试确定该应用程序是否合法并将其秘密。在这两种方法中,您仍然必须解决“此请求是否来自我编写的一段代码”的问题?

让我重复一遍-没有办法在网络上区分特定软件正在运行。如果消息中的数据看起来正确,则无法证明它是另一个正在发送该消息的应用程序

归根结底,如果我正在编写一个恶意应用程序,则我不在乎我是否真正知道真正的秘密,只要我可以让知道该秘密的人代表我来工作即可。因此,如果您认为恶意应用程序可以将您的应用程序模拟到第三方OAuth服务器,那么为什么确定不能将您的应用程序模拟到代理服务器呢?

但是,等等,还有更多。代理服务所在的域是您对客户端和OAuth提供程序的身份(由OAuth提供程序显示给最终用户)。如果恶意应用程序可以使您的服务器做坏事,不仅将吊销您的密钥,而且您的公共Web身份也不再受信任。


我将从明显的内容开始-没有办法在网络上区分特定软件正在运行。如果消息中的数据看起来正确,则无法证明它是另一个正在发送该消息的应用程序。

因此,可以欺骗依赖于应用程序端存储的机密的任何算法。OAuth的优势在于,它永远不会将用户的凭据提供给应用程序,而是为应用程序提供其自己的临时凭据,供用户在必要时撤消。

当然,这里的弱点在于,一个足够好的应用程序可以使用户信任它,而不必在完成其恶毒行为之前就撤销其凭据。

但是,减轻这种情况的一种方法是Google使用三足式OAuth而不是标准的两足式OAuth。在三足式OAuth中,没有预先分配的机密,但是在每次身份验证时,都会发出一个新的访问令牌机密以及每个访问令牌。尽管最终这会遭受相同的缺点,因为不良应用程序可以从其过程中读取优质应用程序的令牌机密,但这确实导致用户每次需要新的访问令牌时都必须批准该应用程序的访问。

当然,这也意味着给用户带来一些不便和烦人。


我已经编辑了问题。我想确保我在问题中所做的假设是正确的。我也不想避免给用户带来不便。所以我看到2个选项。1.冒险,在代码中保守秘密并做一些混淆。或2.进行代理处理,并将机密保存在Web服务器上,我相当确定它不会受到破坏。这是一个公平的结论吗?
ddewaele 2010年

我对此有一个问题。为什么说无法看到代码调用就是您编写的代码。您不能只发送一些链接到您的应用程序签名的令牌,而令牌又链接到您的证书。只有您的应用程序使用您的证书签名,并且该文件仍然保持私有状态。
IgorČordaš2014年

1
我的意思是,使用从此Signature [] sigs = context.getPackageManager()。getPackageInfo(context.getPackageName(),PackageManager.GET_SIGNATURES).signatures获得的值授权对代理服务器的调用。for(Signature sig:sigs){Trace.i(“ MyApp”,“ Signature hashcode:” + sig.hashCode()); }
IgorČordaš14年

为什么我的应用程序不能运行相同的代码,而不是context.getPackageInfo()硬代码"com.your.app_name"
弗朗西·佩诺夫(Francis Penov)2014年

@FranciPenov我认为您的答案缺少重要部分。代理是有好处的,还有另一个原因。它们可以减少某人向第三方提出的请求的范围。在您的代理中,您可以定义允许与第三方的呼叫。
Tijme '18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.