我正在使用PHP library for OAuth2.0 v20
在draft20中,有一个mention of the use of state to prevent CSRF
到目前为止,我自己的实现此PHP库的Web应用程序允许以下内容:
我是否需要在上述所有3种情况下使用状态?
如果是这样,“状态”的一个好例子是什么?
是什么让一个好的“国家”?任何理想的长度?任何最小长度?任何最大长度?
任何理想的化妆品?字母数字包括大写?
答案 0 :(得分:34)
通过示例CSRF漏洞可能会有所帮助,以便了解状态参数如何减轻此类攻击。在此示例中, Mallory 是攻击者, Alice 是受害者。
Mallory访问了一些客户网站,并开始授权该客户使用OAuth访问服务提供商
客户要求服务提供商授权代表Mallory代表请求访问权限
Mallory被重定向到服务提供商的网站,在那里她通常会输入用户名/密码以授权访问
相反,Mallory陷阱/阻止此请求并保存其网址
现在,Mallory不知何故让Alice访问该网址。如果Alice使用自己的帐户登录服务提供商,则她的凭据将用于颁发授权码
授权代码交换访问令牌
现在客户端上的 Mallory 帐户有权访问服务提供商上的 Alice 帐户
那么,我们如何使用state
参数来阻止这种情况?
客户端应该创建一个基于原始用户帐户(例如,用户的会话密钥的哈希)的值。只要它的唯一并使用一些关于原始用户的私密,不可饶恕的信息生成它并不重要。
此值在上面第三步的重定向中传递给服务提供商
现在,当Mallory让Alice访问保存的URL时(上面的第五步),该URL包含使用Mallory的会话信息生成的state
参数
授权代码将与 Alice的会话一起发送并发送回客户端以及Mallory的state
参数
客户端根据 Alice 会话信息生成新的state
值,并将其与从{em>发回的state
值进行比较对服务提供商的授权请求。此值与请求中的state
参数不匹配,因为state
值是基于 Mallory的会话信息生成的,因此会被拒绝。
攻击者无法为任何特定用户生成状态值,因此欺骗用户访问其授权URL无效。
答案 1 :(得分:16)
仅使用授权码流程进行#1 - 3条腿授权。
当您的应用程序交换访问令牌的授权代码时,您希望确保导致所提供的授权代码的OAuth流实际上是由合法用户启动的。因此,在客户端应用程序通过将用户重定向到提供程序来启动OAuth流之前,客户端应用程序会创建一个随机状态值,并通常将其存储在服务器端会话中。然后,当用户完成OAuth流程时,您检查以确保状态值与存储在用户服务器端会话中的值匹配 - 这表示用户已启动OAuth流程。
状态值通常应该是伪随机不可评估的值。可以使用PHP中的rand()函数生成一个简单的值作为int,尽管您可能会变得更复杂以提供更好的保证。
状态的存在是为了防止像我这样的事情通过电子邮件向您发送链接,其中包含我的帐户的授权代码,您点击它并且应用程序将所有数据推送到我的帐户中,这是您不知道的。
OAuth 2.0威胁模型文档中提供了一些其他信息: http://tools.ietf.org/html/draft-ietf-oauth-v2-threatmodel-00
特别参见CSRF保护部分: http://tools.ietf.org/html/draft-ietf-oauth-v2-26#section-10.12
答案 2 :(得分:-3)
因为“状态”只是一个随机字符串,所以制作这样的东西应该可以解决问题:
$state = md5(uniqid(rand(), TRUE));
请记住将其保存在会话中,以便日后查看。