我已经为我的自定义 TYPO3 扩展实现了 CSRF 保护(根据文档),它对未经身份验证的前端访问者和前端的后端管理员都很好地工作。我注意到的一件奇怪的事情是,如果非管理员后端用户尝试使用前端插件中的表单,则会引发错误:
PHP Catchable Fatal Error: Argument 1 passed to TYPO3\CMS\Core\FormProtection\FormProtectionFactory::getMessageClosure() must be an instance of TYPO3\CMS\Lang\LanguageService, null given
Run Code Online (Sandbox Code Playgroud)
我使用 TYPO3 V. 7.6.10 和 7.6.14 进行了测试。两个版本都会出现这个错误。
我查看了 FormProtectionFactory 中的源代码,它似乎$GLOBALS['Lang']是为 FE 中的管理员用户初始化的,但对于普通后端用户来说是空的。在 BE 中,两个用户组都可以访问其他 CSRF 保护的表单。
根据LanguageService的官方参考,LanguageService 通常只在 BE 可用:
这个类通常被实例化为全局变量 $GLOBALS['LANG'] 它只在后端可用,在某些情况下在前端可用
有谁知道这些特定情况是什么?当然可以从 BE 注销并以未经身份验证的用户身份访问表单,但这显然很烦人。我认为这是预期的行为,但我不明白为什么这个问题只发生在非管理员身上。也许有人有一个想法,如何使表单也可供 FE 中的非管理员后端用户使用?
任何帮助都受到高度赞赏。
谢谢!
为了完整起见,我调用了 CSRF 令牌生成器,但我认为“问题”出在 TYPO3 本身(或预期行为)中:
$this->view->assign("csrfToken", FormProtectionFactory::get()->generateToken($this->extensionName,
$this->controllerContext->getRequest()->getControllerActionName(), $additionalObject));
Run Code Online (Sandbox Code Playgroud)
TYPO3 开发人员认为 CSRF 仅适用于已登录的用户,但这里的情况并非如此,因此 CSRF 功能根本无法在匿名用户的前端使用。
请参阅https://forge.typo3.org/issues/77403