Php 我的CSRF保护方法安全吗?

Php 我的CSRF保护方法安全吗?,php,ajax,security,csrf,csrf-protection,Php,Ajax,Security,Csrf,Csrf Protection,我一直在用PHP做我自己的CSRF保护。从我所读到的内容来看,我决定使用cookie来实现我的保护,但对于我的方法是否能够抵御CSRF攻击感到有点困惑 因此,我的方法如下: 用户发送登录请求 服务器检查是否设置了CSRF令牌,如果未设置,则创建一个,并将其存储在会话中,并使用令牌创建Cookie 通过检查CSRF令牌是否在POST请求中进行验证,如果不在POST请求中,则检查$\u COOKIE中的令牌 如果令牌无效,请发回消息 我决定使用cookie来存储令牌,因为这将适用于Ajax请求,并且

我一直在用PHP做我自己的CSRF保护。从我所读到的内容来看,我决定使用cookie来实现我的保护,但对于我的方法是否能够抵御CSRF攻击感到有点困惑

因此,我的方法如下:

  • 用户发送登录请求

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

  • 通过检查CSRF令牌是否在POST请求中进行验证,如果不在POST请求中,则检查$\u COOKIE中的令牌

  • 如果令牌无效,请发回消息

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

    我感到困惑的是,攻击者不能仅仅发出请求;POST或GET,因为cookie在那里,所以它只是随请求一起发送,因此是一个有效的请求,因为令牌每次都随浏览器发送?

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

    我感到困惑的是,攻击者不能仅仅发出请求;POST或GET,因为cookie在那里,所以它只是随请求一起发送,因此作为有效的请求,因为令牌每次都随浏览器一起发送

    对。CSRF代币不是秘密。他们只是确认只有在发出预期的GET请求后才发出POST。也就是说,只有在一开始就要求提交表格的情况下,才能提交表格。它可以防止一个不好的站点通过帖子将用户发送到您的站点。它不会阻止攻击者发出GET请求、获取令牌和发布有效帖子

    发件人:

    借助社会工程(如通过电子邮件或聊天发送链接),攻击者可以诱使web应用程序的用户执行攻击者选择的操作。如果受害者是普通用户,成功的CSRF攻击会迫使用户执行状态更改请求


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

    如果你想检查一个随cookie一起发送的CSRF,你会绕过CSRF背后的想法

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

    <form method="method" action="http://site-to-gain-access-to.tld/someactionurl">
      <!-- some form data -->
    </form>
    
    
    
    这个隐藏的表单将使用javascript执行,无需用户干预。如果用户登录到站点
    站点以访问.tld
    ,并且如果没有激活的CSRF保护,那么就好像用户自己触发了该操作,因为用户的会话cookie将随该请求一起发送。因此服务器会假定是用户触发了该请求

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

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

    因此,突出显示的部分:

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

    通过检查CSRF令牌是否在POST请求中进行验证,如果不在,则检查$\u COOKIE中的令牌


    会破坏CSRF保护。CSRF是否以明文或服务器端加密方式存储在cookie中并不重要。

    我相信更适合您。浏览器会阻止跨站点请求,因此cookie中包含有效CSRF令牌的任何请求通常来自浏览您自己域的客户端(除非您在某些路由中启用CORS,否则您需要小心).是一本很好的读物this@apokryfos不,浏览器通常不会阻止跨站点请求。它们会阻止您希望返回数据的请求。
    XMLHttpRequest
    使用CORS。但是使用JavaScript提交的隐藏
    仍然可以向外部域发送POST请求。此类请求将包括用户。将CSRF存储在Cookie中就好像您没有CSRF令牌一样。@apokryfos涉及这一点的相关部分是
    […]在此规范之外生成的简单跨源请求(例如使用GET或POST的跨源表单提交或由脚本元素生成的跨源GET请求)通常包括用户凭据,因此符合此规范的资源必须始终准备好使用凭据进行简单的跨源请求。[…]
    ()因此,如果我只是将我的令牌作为隐藏输入包含在每个表单中,并使用存储在会话变量中的令牌验证令牌,这还不够吗?您是说令牌也应该是表单操作中GET请求的一部分吗?将令牌包含在隐藏输入元素中就足够了(只要您的站点不更改GET请求上的数据)。我刚才解释了令牌是在GET请求期间生成的(用表单检索页面)。您可以使用cookie或hidden input元素,然后在帖子中再次提交令牌。因此,您是否可以忽略在表单中放置隐藏输入,而只依赖每次发送的cookie?cookie需要一些额外的注意事项。我在其他人的评论和帖子中看到了这些内容。请阅读OWASP链接中的相关页面我提供了。好的,好的,我想这对我来说是清楚的。如果我是正确的,那么在我想要发送的表单中只包含CSRF令牌作为隐藏输入,然后在服务器上的会话中将其与令牌进行比较就足以防止CSRF攻击了?是的,您应该只将其作为隐藏输入包含在表单中,并与服务器进行比较ide会话存储。它是