是我的CSRF保护方法安全



我一直在使用PHP进行自己的CSRF保护。根据我阅读的内容,我决定使用cookie来实现我的保护

所以我的方法遵循:

  1. 用户发送请求登录

  2. 服务器检查是否设置了CSRF令牌,如果不是创建一个并将其存储在其会话中,并使用令牌和令牌也创建一个cookie

  3. 通过检查CSRF令牌是否在邮政请求中,如果不是在$ _COOKIE

  4. 中检查令牌
  5. 如果令牌无效,请发送回消息...

我决定使用cookie存储令牌,因为这将适用于Ajax请求,并且每次使用Ajax帖子时都不必包括它。

我感到困惑的是,攻击者不能只是提出请求。帖子或获取,因为cookie在那里,它还是随着请求发送的,因此是有效的请求,因为每次都会随浏览器发送令牌?

cookie不应包含CSRF令牌。只有客户端会话存储应包含它。而且您不应该反对饼干中的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令牌必须始终仅作为请求主体或URL的一部分发送,而不是作为cookie。

所以突出显示的部分:

服务器检查是否设置了CSRF令牌,如果不是创建一个并将其存储在他们的会话中,并使用令牌以及

创建 cookie

通过检查CSRF令牌是否在POST请求中,如果不是,请检查$ _COOKIE中的令牌

将打破CSRF保护。CSRF是将CSRF存储在Cookie中还是服务器端加密都没有关系。

只要"用户发送请求登录"是指登录页面的初始获取请求,这是正确的。CSRF应生成并存储在Get请求上并在每个帖子中进行验证。

我感到困惑的是,攻击者不能只是提出请求。帖子或获取,并且因为cookie在那里,它还是随着请求发送的,因此是有效的请求,因为每次都会随浏览器发送令牌?

是。CSRF代币并不是秘密。他们只是简单地确认只有在提出预期的请求之后才发表帖子。这意味着只有某人首先请求表格时才能提交表格。它可以防止不良站点通过帖子将用户发送到您的网站。它不会阻止攻击者提出get请求,抓取令牌并发表有效的帖子。

来自OWASP:

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

最新更新