安全威胁的单一标志! FACEBOOK access_token 广播中的 open/clear
Posted
技术标签:
【中文标题】安全威胁的单一标志! FACEBOOK access_token 广播中的 open/clear【英文标题】:SINGLE SIGN ON SECURITY THREAT! FACEBOOK access_token broadcast in the open/clear 【发布时间】:2011-06-30 06:49:07 【问题描述】:2011 年 2 月 20 日:
今天,Facebook 证实确实有一个电话公开广播了 access_token。 . .它恰好是我用来确保用户在保存到我的应用程序数据库之前仍然登录的一个调用。他们的建议是使用上个月为 canvase 和 facebook 提供的 SSL 选项。在大多数情况下,Auth 和 Auth 是安全的。
调查结果:
在我发帖之后,有人说这不是一个真正的问题,但我认为我确实假设了一个问题。所以这里没有含糊不清的问题是:
由于在 Canvas 加载过程中没有从 Facebook 发送的数据在某些时候没有被泄露,包括 access_token、会话和其他可以唯一识别用户的数据,除了添加一个之外,任何人都会看到其他方式吗?更多层,即密码,通过 HTTPS 与 access_toekn 一起通过网络发送,这将确保用户唯一不受篡改的安全性?
我使用 Wireshark 在加载 Canvas 应用程序页面时捕获了本地广播。我非常惊讶地看到 access_token 广播是公开的,任何人都可以看到。此 access_token 会附加到对 Facebook OpenGraph API 的任何 https 调用。
使用 facebook 作为单击登录现在引起了我的极大关注。它存储在内存中的会话对象中,并且在应用程序终止时清除 cookie,在查看 FB.Init 调用后,我看到了很多 HTTPS 调用,所以我假设 access_token 总是加密的。
但昨晚我在状态栏中看到一个来自简单的 http 调用的调用,其中包含 App ID,所以我觉得我应该嗅探 Application Canvas 加载序列。
今天我确实嗅到了广播,在所附图像中,您可以看到有 http 调用,其中 access_token 正在公开广播,任何人都可以访问。
我是否遗漏了什么,是我所看到的并且我的解释真的正确。如果有人可以嗅探并获取 access_token,理论上他们可以通过 https 调用 Graph API,即使回调仍然需要是在 Facebook 的应用程序设置中建立的站点。
但真正的安全威胁是任何人使用 access_token 访问自己的站点。如果唯一被确定为安全的是 access_token,我看不到通过 Facebook 单点登录的价值——因为我可以清楚地看到它并不安全。永不过期的访问令牌不会更改。每个用户的 Access_token 都是不同的,访问另一个站点可能仅限于单个用户,但即使是泄露单个用户的数据也是不可接受的。
http://www.creatingstory.com/images/InTheOpen.png
返回并对此进行了更多研究:
发现:
返回并重新运行画布应用程序以验证不是我的任何代码都没有广播。
在此调用中:HTTP GET /connect.php/en_US/js/CacheData HTTP/1.1
用户 ID 在 cookie 中清晰可见。所以 USER_ID 是完全可见的,但它们已经是。任何人都可以访问几乎任何页面并将鼠标悬停在图像上并查看用户 ID。所以没有大的威胁。 APP_ID 也很容易获得 - 但是。 . .
http://www.creatingstory.com/images/InTheOpen2.png
上述文件通过 Facebook 发起的调用在 OPEN 中清楚地显示了 FULL ACCESS TOKEN。
我错了吗。告诉我我错了,因为我想在这件事上犯错。
我已经重置了我的应用程序密码,所以我正在显示正在加载的画布页面的真实嗅探。
附加数据 02/20/2011:
@ifaour - 感谢您花时间整理回复。
我对 OAuth 流程非常熟悉,并且对 signed_request 解包和 access_token 的使用有相当深入的了解。我在服务器上执行了大量的处理,我的 Facebook 服务器端流程都是完整的并且可以正常运行,没有任何我知道的缺陷。应用程序机密是安全的,永远不会传递给前端应用程序,并且还会定期更改。我对安全非常***,因为我知道有很多我不知道的东西可能会回来咬我。
两个巨大的 access_token 问题:
这些问题涉及可能使用来自 USER AGENT(浏览器)的 access_token。在 Facebook javascript SDK 的 FB.INIT() 过程中,会创建一个 cookie 以及内存中称为会话对象的对象。该对象与 cookie 一起包含 access_token、会话、秘密以及连接的 uid 和状态。会话对象的结构既支持新的 OAuth 也支持旧的流。使用 OAuth,access_token 和 status 几乎都是在 session 对象中使用的。
第一个问题是 access_token 用于对 GRAPH API 进行 HTTPS 调用。如果您有 access_token,则可以从任何浏览器执行此操作:
https://graph.facebook.com/220439?access_token=...
它会返回大量关于用户的信息。因此,任何拥有访问令牌的人都可以访问 Facebook 帐户。您还可以对用户已授予对与 access_token 绑定的应用程序的访问权限的任何信息进行额外调用。起初我认为对 GRAPH 的调用必须对应用程序设置中建立的 URL 进行回调,但我如下所述对其进行了测试,它会将信息直接返回到浏览器中。我认为添加回调功能是一个好主意,可以稍微收紧一些。
第二个问题是利用一些独特的私人安全数据来识别第三方数据库的用户,即,就像在我的情况下,我会使用单点登录将用户信息填充到我的数据库中,使用这种独特的安全数据项(即 access_token,其中包含 APP ID、USER ID 和带有秘密序列的散列)。这些都不是服务器端的问题。你得到一个签名请求,你用秘密解压它,进行 HTTPS 调用,得到 HTTPS 响应。当用户通过 USER AGENT(浏览器)输入必须通过 POST 存储的信息时,此唯一的安全数据元素将通过 HTTPS 发送,以便在插入数据库之前对其进行验证。
但是,如果没有通过单点登录过程提供的受保护的唯一数据片段,则无法保证未经授权的访问。 access_token 是 Facebook 用来对 GRAPH API 进行 HTTPS 调用的数据。它在 USER 和 APPLICATION 方面都被认为是唯一的,并且最初通过 signed_request 包装是安全的。但是,如果它随后以明文形式传输,并且如果我可以嗅探电线并获得 access_token,那么我可以伪装成应用程序并获得他们授权应用程序查看的信息。我在 Safari 和 IE 浏览器中尝试了上面的示例,它在浏览器中将我的所有信息返回给我。
总之,access_token 是 signed_request 的一部分,这也是应用程序最初获取它的方式。在 OAuth 身份验证和授权之后,即 USER 登录 Facebook 然后运行您的应用程序,access_token 如上所述存储并且我已经嗅探它,因此我看到它存储在通过网络传输的 Cookie 中,导致没有唯一的安全可识别信息可用于支持与数据库的交互,或者换句话说,除非还有一条安全数据与 access_token 一起发送到我的数据库,即密码,我会无法辨别是否是合法呼叫。幸运的是,我通过 POST 使用了安全 AJAX,并且调用必须来自同一个域,但我确信有办法劫持它。
我完全愿意接受有关此主题的任何想法并且 access_token 在网络上始终是安全的。
Mahalo nui loa 提前。
【问题讨论】:
哇,如果这是对的,那就太可怕了。我想唯一安全的方法就是把 JS api 一起扔掉,然后在服务器端做所有的 oauth/graph 请求。 对我来说,最大的问题是如果您使用单点登录,然后页面上的数据需要保存回数据库,而您所拥有的只是 facebook 凭据,您仅限于您可以使用什么与您的安全 POST 一起发送到数据库以验证请求。我打算使用完整的 access_token 和其他一些凭据,但即使是这些凭据也是在 access_token 的基础上创建的。 access_token 在签名请求中发送,然后解密。为什么还要公开重播呢。 . .我希望我的分析完全不正确。 . . 最近有人尝试公开此类问题:en.wikipedia.org/wiki/Firesheep @bdonlan “我错过了什么吗,这是我所看到的,我的解释真的正确。如果有人可以嗅探并获得 access_token,他们理论上可以通过 https 调用 Graph API,即使回调仍然需要是在 Facebook 的应用程序设置中建立的站点。”您一定没有看到他要求 SO-ers 检查他的逻辑并回复他的请求。 请不要全部大写。这是冒犯性的。 【参考方案1】:我对 Facebook 的身份验证/授权方法不是很熟悉,但我相信他们为委派、分布式授权和“单点登录”实现了oauth(或类似的方法)。
OAuth is described by RFC-5849
编辑:Facebook 使用的 OAuth 2.0 仍在工作草案中。
在 OAuth 和类似系统中,“access_token”只是图片的一部分。通常还有一个密钥,只有服务提供商(facebook)和客户端应用程序(您的应用程序)知道。密钥是唯一需要保密的部分 - 并且该部分从通过网络发送(在首次发布之后)。
在 Facebook 的情况下,我认为密钥是在您注册应用程序以使用他们的 API 时分配给您的,并且只要用户同意允许您的应用程序,给定用户的“access_token”就会返回给您访问他们的信息。
消息以明文形式发送,包括用户的用户名和相关的“access_token”;但是,每条消息还必须包含有效签名才能被服务器接受。签名是一个加密计算的字符串,它是使用称为HMAC 的技术创建的。
计算 HMAC 签名需要 token 和 secret,并且还包括消息的其他关键部分。每个签名对于给定的消息内容都是唯一的;并且每条消息都使用nonce 来确保没有两条消息完全相同。
当服务器接收到签名消息时,它首先提取 access_token(明文),并确定令牌是为哪个应用程序颁发的。然后它从它自己的本地数据库中检索匹配的secret(该秘密不包含在消息中)。最后,服务器使用明文消息、明文 access_token 和密钥来计算消息的预期 HMAC 签名。如果计算出的签名与接收到的消息上的签名匹配,那么消息一定是由知道相同secret的人(即您的应用程序)发送的。
查看Section 3.1 of RFC-5849 以获取 OAuth 特定示例,并进一步详细说明。
顺便说一句,Amazon 使用相同的方法来控制对 S3 和 EC2 以及大多数其他提供长期授权 API 访问的服务提供商的访问。可以这么说 - 这种方法是安全的。一开始可能有点违反直觉,但仔细考虑后就会明白。
添加一些来自 Facebook 文档的链接和引用:
Facebook 确实在使用HMAC-SHA256
算法。 注册文件(PHP Example reading signed_request 部分)。
始终验证signed_request
:
Authentication Document 包含许多有用的信息,这些信息与您可以用来验证用户身份的不同流程有关。另请阅读页面底部的如果您无法验证
signed_request
因为你不能嵌入 您的应用程序机密(例如在 javascript 或桌面应用程序) 那你MUST
只用一张 来自有效载荷的信息,oauth_token
.
Security Considerations
部分:
跨站请求伪造是一种 受信任的攻击 (经过身份验证和授权的)用户 不知不觉地执行了一个动作 网站。为了防止这种攻击,你 应该在状态中传递一个标识符 参数,然后验证状态 响应中的参数匹配。我们 强烈建议任何应用程序 实现 Facebook 用户登录 使用此实现 CSRF 保护 机制。
【讨论】:
+1。如果可以的话,我已经添加了几个链接和引号来支持你的回答。 02/20/2011:Facebook 今天证实确实有一个电话公开广播了 access_token。 . .它恰好是我用来确保用户在保存到我的应用程序数据库之前仍然登录的一个调用。他们的建议是使用上个月为 canvase 和 facebook 提供的 SSL 选项。在大多数情况下,Auth 和 Auth 是安全的。【参考方案2】:Facebook 确认确实有一个调用公开广播了 access_token - 它恰好是我用来确保用户在保存到我的应用程序数据库之前仍然登录的一个调用。他们的建议是使用上个月为画布和整个 Facebook 提供的 SSL 选项。在大多数情况下,Auth 和 Auth 是安全的。
为确保第三方应用程序与 Facebook 应用程序甚至任何使用 Facebook 单点登录的网站之间的安全接口,当与 access_token 结合使用时,身份问题将提供额外的层。
或者要求您的用户通过 Facebook 和 Facebook Canvas 应用程序的新 SSL 功能使用 Facebook。如果 access_token 是公开广播的,则当需要在数据库交互之前确认身份时,它不能用于唯一标识第三方数据库中的任何人。
【讨论】:
以上是关于安全威胁的单一标志! FACEBOOK access_token 广播中的 open/clear的主要内容,如果未能解决你的问题,请参考以下文章
补丁发布8个月仍有超过7万台Memcached服务器受安全威胁