我一直在使用PHP进行自己的CSRF保护.根据我的阅读,我决定使用cookie来实现我的保护,但是对于我的方法是否可以抵御CSRF攻击感到有点困惑.
所以我的方法如下:
>用户发送登录请求
>服务器检查是否设置了CSRF令牌,如果没有设置,则将其存储在会话中并使用令牌创建Cookie
>通过检查是否在POST请求中验证CSRF令牌,如果没有,则在$_COOKIE中检查令牌
>如果令牌无效,则发回消息…
我决定使用cookie来存储令牌,因为这将适用于Ajax请求,每次使用Ajax POST时我都不必包含它.
我感到困惑的是攻击者不能提出请求; POST或GET,因为cookie就在那里它无论如何都会随请求一起发送,因此每次都会随浏览器一起发送令牌,这是一个有效的请求?
解决方法:
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发送.
所以突出显示的部分:
Server checks if a CSRF token is set, if not create one and store it in their Session and create a Cookie with the token as well
Validate the CSRF token through checking if it is in the POST request, if not then check for the token in $_COOKIE
会打破CSRF保护. CSRF是以明文还是服务器端加密存储在cookie中无关紧要.