提问人:Kobus Myburgh 提问时间:10/6/2023 最后编辑:Kobus Myburgh 更新时间:11/21/2023 访问量:45
Codeigniter 3 系统 - 启用 CSRF 保护会导致致命错误 CI_Controller not found
Codeigniter 3 system - enabling CSRF protection causes a fatal error CI_Controller not found
问:
我正在开发一个基于 CodeIgniter 3 的系统,并且有人要求在登录和注册表单上启用 CSRF。
在我的配置文件中,我完成了:
$config['csrf_protection'] = FALSE;
if (isset($_SERVER["REQUEST_URI"])) {
if (stripos($_SERVER["REQUEST_URI"], '/login') !== FALSE || stripos($_SERVER["REQUEST_URI"], '/register') !== FALSE ) {
$config['csrf_protection'] = TRUE;
}
}
但是当我尝试将配置变量设置为 true 时,我的错误处理程序会触发函数不存在。这个函数确实存在于我的函数中,并且该错误具有误导性,因为它实际上抱怨没有首先找到这个函数,但实际的错误是应该没有找到,最初导致我相信 CodeIgniter 实例没有被识别,即使回溯表明不是这样:csrf_protection
MY_url_helper
CI_Controller
Array
(
[0] => Array
(
[file] => path\to\system\core\Exceptions.php
[line] => 268
[function] => include
)
[1] => Array
(
[file] => path\to\system\core\Common.php
[line] => 627
[function] => show_php_error
[class] => CI_Exceptions
[object] => CI_Exceptions Object
(
[ob_level] => 1
[levels] => Array
(
[1] => Error
[2] => Warning
[4] => Parsing Error
[8] => Notice
[16] => Core Error
[32] => Core Warning
[64] => Compile Error
[128] => Compile Warning
[256] => User Error
[512] => User Warning
[1024] => User Notice
[2048] => Runtime Notice
)
)
[type] => ->
[args] => Array
(
[0] => Error
[1] => Uncaught Error: Class "CI_Controller" not found in path\to\system\core\CodeIgniter.php:369
Stack trace:
#0 path\to\app\core\MY_Exceptions.php(54): get_instance()
#1 path\to\system\core\Common.php(195): MY_Exceptions->__construct()
#2 path\to\system\core\Common.php(656): load_class('Exceptions', 'core')
#3 [internal function]: _exception_handler(Object(Error))
#4 {main}
thrown
[2] => core/CodeIgniter.php
[3] => 369
)
)
[2] => Array
(
[file] => path\to\system\core\Common.php
[line] => 693
[function] => _error_handler
[args] => Array
(
[0] => 1
[1] => Uncaught Error: Class "CI_Controller" not found in path\to\system\core\CodeIgniter.php:369
Stack trace:
#0 path\to\app\core\MY_Exceptions.php(54): get_instance()
#1 path\to\system\core\Common.php(195): MY_Exceptions->__construct()
#2 path\to\system\core\Common.php(656): load_class('Exceptions', 'core')
#3 [internal function]: _exception_handler(Object(Error))
#4 {main}
thrown
[2] => path\to\system\core\CodeIgniter.php
[3] => 369
)
)
[3] => Array
(
[function] => _shutdown_handler
[args] => Array
(
)
)
)
如果从我能看到的所有迹象来看,CodeIgniter 已加载,我对它如何不工作感到非常困惑。代码库扩展了 CI_Exceptions 类,这是我现在用于测试的构造函数:
class MY_Exceptions extends CI_Exceptions
{
public function __construct() {
parent::__construct();
die('Error is showing');
$this->CI =& get_instance();
die('Error not showing');
}
}
不知何故,当分配实例时,一切都变成了梨形。
这个问题:激活 CSRF 保护时出错提供了一些看起来相同的信息,但接受的答案并不是我可以实现的真正答案。
将我的 CI 错误日志记录设置为级别 4(所有消息)给我这个:
INFO - 2023-10-06 13:47:57 --> Config Class Initialized
INFO - 2023-10-06 13:47:57 --> Hooks Class Initialized
DEBUG - 2023-10-06 13:47:57 --> UTF-8 Support Enabled
INFO - 2023-10-06 13:47:57 --> Utf8 Class Initialized
INFO - 2023-10-06 13:47:57 --> URI Class Initialized
INFO - 2023-10-06 13:47:57 --> Router Class Initialized
INFO - 2023-10-06 13:47:57 --> Output Class Initialized
INFO - 2023-10-06 13:47:57 --> Security Class Initialized
DEBUG - 2023-10-06 13:47:57 --> Global POST, GET and COOKIE data sanitized
此日志中没有任何错误。
有什么想法吗?
答:
我终于找到了一个非常不优雅的修复程序(也违背了最佳实践,但由于缺乏更好的解决方案,这将不得不这样做)。
CodeIgniter 3 CSRF/Security 实现似乎在初始化它需要满足请求的类之前调用了过程函数。它似乎发生在某种循环中,因为它只在第一次失败,然后所需的类似乎被初始化,第二次开始它工作。这是我能想到的最好的解释 - 可能完全偏离基础,但我的修复有效。get_instance()
注意::我知道不要更改系统的核心文件,并且我理解围绕它的逻辑,但这不是一个类。它是过程代码,所以不能扩展它。然后,我尝试调整和扩展引用的类,但这很快就变得混乱了 - 所以如果有人有更好的解决方案,我愿意接受建议。
从这里改变:system\core\CodeIgniter.php
function &get_instance()
{
return CI_Controller::get_instance();
}
对此:
function &get_instance()
{
if (class_exists('CI_Controller')) {
return CI_Controller::get_instance();
}
}
为我解决了问题,没有任何其他问题,CSRF 按预期工作。看起来好像第一次调用此方法时,类尚未初始化。回溯没有给我足够的信息来追踪这种情况的实际发生位置。get_instance()
评论