没有会话或数据库的安全CSRF保护?

时间:2015-04-19 18:30:27

标签: php security session cookies csrf-protection

我试图对HTML登录表单实施安全的CSRF保护, 我知道实现CSRF保护的最佳方法是在会话中存储随机csrf_key, 但我想将CSRF添加到我的登录名和注册表格...我不想为任何匿名的未注册用户存储许多会话......

所以我想创建最好的安全posibble而不使用会话或数据库,只有表单隐藏字段/&一个cookie,登录后我会使用session csrf protection。

我对secure user_storage的想法只有csrf:

csrf_token = AES(ip + useragent + timestamp + random_data,csrf_aes_site_key)

当csrf_aes_site_key在配置文件中进行硬编码时。 并且在每次登录/注册之后,我将解密AES字符串+ velidate,ip& ua与请求ip& ua匹配,并且时间戳不会过于匹配,比如5分钟(如果csrf_timestamp + 18000> = current_ts),并且random_data只是随机性(并确保同一用户在相同的ts中多次请求时不会获得相同的csrf_token)...

所以......它足够安全,它是一个很好的解决方案吗? 如果没有,还有其他建议可以解决这个难题吗? 谢谢!

修改: 我刚刚创建的实现,它工作正常,但它是否足够好?

完整示例: https://github.com/itaiarbel/aes_based_csrf_protection

问题1: 用户可以使用csrf_token并在接下来的5分钟内使用相同的令牌成功提交到表单 错误?如果用户提交多次,我该怎么办?只要不是csrf攻击......

问题2: 如果页面打开5分钟,用户将忘记登录, (每5分钟自动重新登录页面?maby将其更改为1小时?)

您是否可以通过此实施发现任何特定的安全风险?或者我可以假设这是一种安全的CSRF保护方式吗?

3 个答案:

答案 0 :(得分:6)

将CSRF令牌存储在cookie中的方法被广泛使用(AngularJSDjango),但它的工作方式略有不同。服务器在 cookie 中发送令牌,客户端使用JavaScript读取cookie,并在 HTTP标头反映令牌。服务器应该只验证HTTP标头中的值,即使cookie也会自动发送。

只要JavaScript前端和后端都知道它们,实际的cookie和标题名称就不重要了。

这可以防止CSRF,因为只有从真实来源运行的JavaScript才能读取cookie(请参阅维基百科上的detailed discussion)。令牌可以是会话cookie的HMAC,这样就无需记住服务器端的令牌状态。

主要优点是这种方法(与表单字段中具有令牌的方法不同)适用于基于JavaScript的单页应用程序,在该应用程序中,您不在服务器上生成HTML,并且无法真正嵌入CSRF令牌他们的代码。

答案 1 :(得分:0)

它适用于大多数客户端 - 但在客户端通过负载平衡代理(您看到的客户端IP更改)访问您的站点时会失败。一个更正确的解决方案是使用来自whois记录或ASN号码的组织数据,但是在查看这些数据时需要花费一些费用 - 这取决于仅使用(IPV4)地址的最后16位的流量。可能已经足够了。

您可能还会遇到问题,具体取决于您存储的用户代理的数量(Google Chrome浏览器可以动态更新)。

答案 2 :(得分:0)

对我来说非常不安全。不要使用这个。登录表单和注册表单需要全面的CSRF保护;使用任何类型的简化保护都是不可接受的。

您的设置似乎容易受到位于同一NAT(从而共享IP地址)后面的任何人的攻击,这在人们的家庭甚至许多工作场所中都很常见。这是一个示例方案:

  1. 恶意同事(MC)在网站上注册了一个新帐户
  2. MC找出受害者的用户代理,这很容易
  3. MC在发送受害者的用户代理的同时从网站获取CSRF令牌
  4. MC制作了一个恶意网站,其中包含:
    • 隐藏的登录表单,该表单会在加载时自动提交
    • 上面的CSRF令牌
    • 逗猫模因
  5. MC发送链接给受害者,说“哈哈,看看这个”
  6. 受害者很喜欢模因,但现在在他们不知情的情况下登录了网站
  7. MC说服受害者开始使用该网站,并在已登录的帐户上生成数据或元数据
  8. MC可以查看所有这些数据,因为他们可以访问同一帐户

第3步到第6步可以在5分钟内轻松完成。