https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-30#section-10.12说:
客户端必须实现 CSRF 保护 [...] 通常通过要求发送到重定向 URI 端点的任何请求包含将请求绑定到用户代理的身份验证状态的值(例如会话 cookie 的哈希 [... ]
不过,它并没有说太多关于实现的内容。它只是说明了 CSRF 的工作原理:
针对客户端重定向 URI 的 CSRF 攻击允许攻击者注入他们自己的授权代码或访问令牌,这可能导致客户端使用与攻击者的受保护资源相关联的访问令牌,而不是受害者的(例如,将受害者的银行帐户信息保存到受攻击者控制的受保护资源)
但是使用“相当”这个词反而会使声明变得毫无价值。
我正在考虑如何在 GAE 中实现“状态”(使用 Webapp2)。从黑客如何使用 CSRF 对抗 OAuth2 开始,这将是最简单的。我只找到了一篇关于此事的好文章:“Cross Site Request Forgery and OAuth2”。
不幸的是,虽然这篇博文写得很好,但除了解释 OAuth2 之外,没有太多信息。这些例子不起作用,我不知道Spring。尽管如此,我还是在那里发现了一个有趣的建议:连接到 OAuth2 提供程序的服务器应该将“状态”存储为随机会话密钥(例如“this_is_the_random_state”:“this_doesn't_matter”),而不是静态密钥下的值(例如“状态”:“随机状态字符串”)。
我的问题是,“状态”的合理实施是什么?
- 应该对随机生成的状态进行散列处理,还是可以存储相同的值并将其发送给 OAuth2 提供者?
- 如果会话后端是安全 cookie 或服务器端存储技术(例如在 GAE Memcache 或数据库中),这里有什么区别吗?
- 是否应该按照建议将状态存储为密钥?
- 状态是否应该有有效期,或者会话(如果有的话)生命周期是否足够?