我的CSRF保护方法是否安全?

时间:2017-09-27 13:38:14

标签: php ajax security csrf csrf-protection

我一直在使用PHP进行自己的CSRF保护。根据我的阅读,我决定使用cookie来实现我的保护,但是对于我的方法是否可以抵御CSRF攻击感到有些困惑。

所以我的方法如下:

  1. 用户发送登录请求

  2. 服务器检查是否设置了CSRF令牌,如果没有设置,则将其存储在会话中并使用令牌创建Cookie

  3. 通过检查是否在POST请求中验证CSRF令牌,如果没有,则在$ _COOKIE中检查令牌

  4. 如果令牌无效,则发回消息......

  5. 我决定使用cookie来存储令牌,因为这将适用于Ajax请求,每次使用Ajax POST时我都不必包含它。

    我感到困惑的是攻击者不能提出请求; POST或GET,因为cookie就在那里,无论如何它都会随请求一起发送,因此每次都会随浏览器一起发送令牌,这是一个有效的请求?

2 个答案:

答案 0 :(得分:4)

Cookie不应包含CSRF令牌。只有客户端会话存储应该包含它。而且你不应该反对cookie中的CSRF。

如果您要检查随cookie一起发送的CSRF,您将绕过CSRF背后的想法。

一个简单的攻击场景将是外国网站上隐藏的形式:

<form method="method" action="http://site-to-gain-access-to.tld/someactionurl">
  <!-- some form data -->
</form>

这个隐藏的表单将在没有用户干预的情况下使用javascript执行。如果用户在站点site-to-gain-access-to.tld上登录,并且没有激活CSRF保护,那么就好像用户本身会触发该操作,因为用户的会话cookie将随该请求一起发送。因此服务器会认为是触发该请求的用户。

如果您现在将CSRF令牌放在Cookie中,则会遇到与会话相同的问题。

CSRF令牌必须始终仅作为请求正文或网址的一部分发送,而不是作为Cookie发送。

所以突出显示的部分:

  

服务器检查是否设置了CSRF令牌,如果没有设置,则将其存储在会话中并使用令牌创建 Cookie

     

通过检查是否在POST请求中验证CSRF令牌,如果没有,则检查$ _COOKIE中的令牌

会打破CSRF保护。 CSRF是以明文还是服务器端加密存储在cookie中无关紧要。

答案 1 :(得分:1)

只要“用户发送登录请求”是指登录页面的初始GET请求,这是正确的。应该生成CSRF并将其存储在GET请求中,并在每次POST期间进行验证。

  

我感到困惑的是攻击者不能提出请求; POST或GET,因为cookie就在那里,无论如何它都会随请求一起发送,因此每次都会随浏览器一起发送令牌,这是一个有效的请求?

是。 CSRF代币并不是秘密。他们只是确认在发出预期的GET请求后才进行POST。这意味着,如果他们首先要求提供表格,则他们只能提交表格。它可以防止恶意网站通过POST将用户发送到您的网站。它不会阻止攻击者发出GET请求,获取令牌以及进行有效的POST。

来自OWASP

  

在社交工程的帮助下(例如通过电子邮件或聊天发送链接),攻击者可能会欺骗Web应用程序的用户执行攻击者选择的操作。如果受害者是普通用户,则成功的CSRF攻击可以强制用户执行状态更改请求。