OAuth2.0服务器堆栈如何使用状态来防止CSRF?for draft2.0 v20

Kim*_*cks 13 php oauth oauth-provider oauth-2.0

我在OAuth2.0 v20上使用PHP库

在草案20中,提到了使用国家来防止CSRF

到目前为止,我自己的实现此PHP库的Web应用程序允许以下内容:

  1. 使用授权码请求的3腿认证
  2. 使用资源所有者凭据授权的2腿认证
  3. 刷新访问令牌的请求

我是否需要在上述所有3种情况下使用状态?

如果是这样,"状态"的一个好例子是什么?

是什么让一个好的"国家"?

任何理想的长度?任何最小长度?任何最大长度?

有理想化妆吗?包括大写字母的字母数字?

Way*_*ett 34

单步执行CSRF漏洞可能会有所帮助,以便了解状态参数如何减轻此类攻击.在这个例子中,Mallory攻击者Alice受害者.

攻击

  1. Mallory访问某个客户的网站并开始授权该客户使用OAuth 访问某个服务提供商的过程

  2. 客户端要求服务提供商允许代表Mallory请求访问权限

  3. Mallory被重定向到服务提供商的网站,在那里她通常会输入她的用户名/密码以授权访问

  4. 相反,Mallory陷阱/阻止此请求并保存其URL

  5. 现在,Mallory以某种方式让Alice访问该URL.如果Alice使用自己的帐户登录服务提供商,则其凭据将用于颁发授权码

  6. 授权代码被交换为访问令牌

  7. 现在,Mallory在客户端帐户被授权访问服务提供商处的Alice帐户

那么,我们如何使用state参数来防止这种情况呢?

预防

  1. 客户端应该创建一个以某种方式基于原始用户帐户的值(例如,用户会话密钥的哈希).只要它是唯一的并且使用关于原始用户的一些私有的,不可思议的信息生成它并不重要.

  2. 此值将从上面的步骤3中的重定向传递给服务提供者

  3. 现在,当Mallory让Alice访问保存的URL时(上面的第五步),该URL包含state使用Mallory的会话信息生成的参数

  4. 颁发授权代码并将其与Mallory的参数一起发送回Alice会话中的客户端state

  5. 客户端state基于Alice的会话信息生成新值,并将其与state从授权请求发送回服务提供者的值进行比较.此值state与请求中的参数不匹配,因为该state值是基于Mallory的会话信息生成的,因此会被拒绝.

攻击者无法为任何特定用户生成状态值,因此欺骗用户访问其授权URL无效.

  • 我认为所描述的攻击缺少细节.Mallory陷阱的授权URL并非特定于她的帐户.将此发送给Alice不是问题; Alice将在客户端访问资源提供者的帐户时授予她帐户.当Mallory更改她捕获的URL中的redirect_uri以指向她自己的服务器时(这是OAuth2规范允许的,但不是很常见),就会出现问题.在这种情况下,Mallory的服务器将接收Alice的身份验证令牌.有关详细信息,请参阅https://hueniverse.com/oauth-2-0-redirection-uri-validation-d71202046944. (2认同)

Rya*_*oyd 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