我一直在使用PHP进行自己的CSRF保护。根据我阅读的内容,我决定使用cookie来实现我的保护
所以我的方法遵循:
-
用户发送请求登录
-
服务器检查是否设置了CSRF令牌,如果不是创建一个并将其存储在其会话中,并使用令牌和令牌也创建一个cookie
-
通过检查CSRF令牌是否在邮政请求中,如果不是在$ _COOKIE
中检查令牌 如果令牌无效,请发送回消息...
我决定使用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攻击可以迫使用户执行状态更改请求。