4

2011 年 2 月 20 日:

Facebook 今天证实,确实有一个电话公开广播了 access_token。. . 它恰好是我用来确保用户在保存到我的应用程序数据库之前仍然登录的一个调用。他们的建议是使用上个月为 canvase 和 facebook 提供的 SSL 选项。在大多数情况下,Auth 和 Auth 是安全的。

发现:

在我发帖之后,有人说这不是一个真正的问题,但我认为我确实假设了一个问题。因此,这里没有歧义,这是一个带头的问题:

由于在 Canvas Load 过程中没有从 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_tokens 都是不同的,访问另一个站点可能仅限于单个用户,但即使损害单个用户的数据也是不可接受的。

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。

我错了吗。告诉我我错了,因为我想在这件事上犯错。

我已经重置了我的应用程序密码,所以我展示了正在加载的画布页面的真实嗅觉。

附加数据 2011 年 2 月 20 日:

@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 和状态几乎都是在会话对象中使用的。

第一个问题是 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 提前。

4

2 回答 2

3

我对 Facebook 的身份验证/授权方法不是很熟悉,但我相信他们为委派、分布式授权和“单点登录”实现了oauth(或类似的东西)。

OAuth 由 RFC-5849 描述
编辑:Facebook 使用OAuth 2.0,它仍处于工作草案中。

在 OAuth 和类似系统中,“access_token”只是图片的一部分。通常还有一个密钥,只有服务提供商(facebook)和客户端应用程序(您的应用程序)知道。密钥是唯一需要保密的部分——并且该部分永远不会通过网络发送(在首次发布之后)。

在 Facebook 的情况下,我认为当您注册应用程序以使用他们的 API 时,密钥会分配给您,并且只要用户同意允许您的应用程序访问他们的应用程序,给定用户的“access_token”就会返回给您信息。

消息以明文形式发送,包括用户的用户名和相关的“access_token”;但是,每条消息还必须包含有效签名才能被服务器接受。签名是一个加密计算的字符串,它是使用称为HMAC的技术创建的。

计算 HMAC 签名需要tokensecret,并且还包括消息的其他关键部分。每个签名对于给定的消息内容都是唯一的;并且每条消息都使用一个随机数来确保没有两条消息可以完全相同。

当服务器收到签名消息时,它首先提取 access_token(明文),并确定令牌是为哪个应用程序颁发的。然后它从自己的本地数据库中检索匹配的秘密(秘密包含在消息中)。最后,服务器使用明文消息、明文 access_token 和密钥来计算消息的预期 HMAC 签名。如果计算出的签名与接收到的消息上的签名相匹配,那么消息一定是由知道相同秘密的人(即您的应用程序)发送的。

查看RFC-5849的第 3.1 节以获取 OAuth 特定示例,并进一步详细说明细节。

顺便说一句,亚马逊使用相同的方法来控制对 S3 和 EC2 的访问,以及大多数其他提供长期授权 API 访问的服务提供商。我只想说 - 这种方法安全的。一开始可能有点违反直觉,但是一旦你仔细考虑它就会有道理。


从 Facebook 文档中添加一些链接和引用:

如果您 signed_request因为无法嵌入应用程序机密(例如在 javascript或桌面应用程序中)而无法验证,那么您MUST只使用来自有效负载的一条信息,即 oauth_token.

  • 身份验证文档包含许多有用的信息,这些信息涉及您可以用来对用户进行身份验证的不同流程。另请阅读Security Considerations页面底部的部分:

跨站点请求伪造是一种攻击,其中受信任的(经过身份验证和授权的)用户在不知情的情况下在网站上执行操作。为了防止这种攻击,您应该在 state 参数中传递一个标识符,然后验证响应上的 state 参数匹配。我们强烈建议任何实现 Facebook 用户登录的应用程序都使用此机制实现 CSRF 保护。

于 2011-02-19T19:32:30.297 回答
0

Facebook 确认确实有一个调用,其中 access_token 是公开广播的——它恰好是我用来确保用户在保存到我的应用程序数据库之前仍然登录的一个调用。他们的建议是使用上个月为画布和整个 Facebook 提供的 SSL 选项。在大多数情况下,Auth 和 Auth 是安全的。

为了确保第三方应用程序和 Facebook 应用程序甚至任何使用 Facebook 单点登录的网站之间的安全接口,身份问题与 access_token 一起使用时会提供额外的层。

或者要求您的用户将 Facebook 与 Facebook 和 Facebook Canvas 应用程序的新 SSL 功能一起使用。如果 access_token 是公开广播的,则当需要在数据库交互之前确认身份时,它不能用于唯一标识第三方数据库中的任何人。

于 2011-02-21T07:22:31.080 回答