我试图对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保护方式吗?
答案 0 :(得分:6)
将CSRF令牌存储在cookie中的方法被广泛使用(AngularJS,Django),但它的工作方式略有不同。服务器在 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地址)后面的任何人的攻击,这在人们的家庭甚至许多工作场所中都很常见。这是一个示例方案:
第3步到第6步可以在5分钟内轻松完成。