当前位置: 首页 > 知识库问答 >
问题:

缺少Csrf令牌cookie

阎弘
2023-03-14

我对CakePHP(v3.7)比较陌生。我有一个应用程序,其中出现了“缺少Csrf令牌Cookie”错误。

在pplication.php,我有:

$options = [];        // I'm fine with the default options.
$csrf = new CsrfProtectionMiddleware($options);
$middlewareQueue->add($csrf);

表单页面有一个隐藏的表单元素,其中包含_csrfToken。我不明白为什么没有在邮件上找到它?

深入研究后,我发现在CsrfProttionMiddleware.php中,下面的_validateToken()函数的行为如下:

$cookie为空(没有设置cookie)。)因此,$cookie为空。

$post实际上包含页面上隐藏参数中_csrfToken参数的内容。然而,函数从来不看它。因为$cookie为空,所以if(!$cookie)语句导致抛出InvalidCsrfTokenExcure。

    protected function _validateToken(ServerRequest $request)
    {
        $cookies = $request->getCookieParams();
        $cookie = Hash::get($cookies, $this->_config['cookieName']);
        $post = Hash::get($request->getParsedBody(), $this->_config['field']);
        $header = $request->getHeaderLine('X-CSRF-Token');

        if (!$cookie) {
            throw new InvalidCsrfTokenException(__d('cake', 'Missing CSRF token cookie'));
        }

        if (!Security::constantEquals($post, $cookie) && !Security::constantEquals($header, $cookie)) {
            throw new InvalidCsrfTokenException(__d('cake', 'CSRF token mismatch.'));
        }
    }
}

显然,除了隐藏参数之外,中间件还需要一个实际的cookie。这个cookie设置在哪里(或者应该设置在哪里?)

更新:

我在浏览器端进行了检查。正在设置cookie,但浏览器不会在POST请求中返回cookie。

下面是CakePHP对填充页面的原始GET请求的响应:

Connection: Keep-Alive
Content-Length: 3013
Content-Type: text/html; charset=UTF-8
Date: Wed, 08 May 2019 23:07:31 GMT
Keep-Alive: timeout=5, max=100
Server: Apache/2.4.33 (Unix) PHP/7.1.1
Set-Cookie: csrfToken=b553dd2e06e57f6d514ee41a120e1c60084adafddfbaa6f72db1f7f590fcf50143876ac817d29d6f1cf9a786031d6235ba21e265b9d3b2a0ee4535854f048b66; path=/webroot/
X-Powered-By: PHP/7.1.1

注意csrfToken cookie。...这是浏览器发送回表单数据的POST

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 184
Content-Type: application/x-www-form-urlencoded
DNT: 1
Host: *************
Origin: ****************
Pragma: no-cache
Referer: ***************
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36

查询字符串参数

redirect: /Users/login

表格数据

_method: POST
_csrfToken:  b553dd2e06e57f6d514ee41a120e1c60084adafddfbaa6f72db1f7f590fcf50143876ac817d29d6f1cf9a786031d6235ba21e265b9d3b2a0ee4535854f048b66
username: xxxxxxxxxx
password: xxxxxxxxxx

请注意,它发回隐藏的表单参数_csrfToken,但不是cookie。

谢谢你的帮助。。。

共有1个答案

南门朗
2023-03-14

解决了的。这是Apache中文档根目录设置的一个问题。它被设置为webroot的父目录,而不是webroot本身。当我改变它时,一切都起作用了。

 类似资料:
  • 这是我送的东西。

  • 当我试图从plurk API获取access_token时,我会重新执行“Bad Request 40007:Missing Request Token”

  • 本页描述了解释CSRF攻击的用例(16.1): https://docs.spring.io/spring-security/site/docs/current/reference/html/csrf.html 但是,如果用户确实登录了银行的网站,那么邪恶的网站难道不可能发出GET请求以获取新的CSRF令牌,并在根本不需要用户的情况下撰写帖子吗? 答案必须是否定的,否则CSRF令牌将毫无用处,但我

  • 问题内容: 我有使用mod_wsgi在apache服务器上运行的django,以及由apache(而不是django)直接提供服务的angularjs应用。我想对django服务器进行POST调用(运行rest_framework),但csrf令牌存在问题。 是否可以通过某种方式从服务器设置令牌而不将其作为模板的一部分放置(因为这些页面没有经过django)? 我希望能够通过GET请求以cooki

  • 问题内容: 我在CSRF令牌方面遇到问题。当我提交表单时,正在生成一个新的表单,但是我想我正在生成两个不同的令牌,这有点困惑。还有一个名为的令牌,因此我在开发人员工具中看到了两个不同的cookie(XSRF- TOKEN和_csrf),发布后它们没有变化。 我想要做的是为每个帖子请求生成一个新令牌,并检查它是否有效。我知道为了安全起见应该这样做,但是我坚持了下来。 漫长的一天,我是Express和

  • 问题内容: 我正在尝试从CSRF保护应用程序(PHP和许多JS)。 我想使用令牌。 AJAX完成了许多操作,因此我必须在Javascript中传递令牌。如果我想为每个会话或每个页面加载生成1个令牌,这很简单- 我生成一个新令牌,将其放在DOM中的某个位置,然后使用Javascript查找并发送到处理端。 但是,如果我想为每个操作使用新令牌怎么办?我正在考虑进行ajax调用以重新生成令牌,然后将结果