如何调试 cakephp 3.5 基于缓存的问题?

how to debug cakephp 3.5 cache basedir issue?

我在 cakephp 3 中有一个应用程序,几周前开始报告 open_basedir restriction in effect. File(/) is not within the allowed path(s)。我试图调试它,但没有成功找到原因。该应用程序运行了大约 2.5 年,现在才开始出现,但没有对使用缓存或更改配置的代码部分进行任何更改。在配置中,我为每种缓存模式正确设置了“路径”。而且它也不是来自一致 url/method。它现在随机出现在不到 1% 的电话中。更常见的是第一周左右。有什么办法可以调试并找到原因吗?您知道这种行为的任何可能原因吗?我已经尝试了所有我能想到的但没有成功。

配置示例:

'hour' => [
            'className' => 'File',
            'path' => CACHE,
            'serialize' => true,
            'duration' => '+1 hour',
            'url' => env('CACHE_DEFAULT_URL', null),
        ],

一个例子的调试跟踪:

Cake\Error\BaseErrorHandler::handleError() - CORE/src/Error/BaseErrorHandler.php, line 153
is_dir - [internal], line ??
Cake\Cache\Engine\FileEngine::_clearDirectory() - CORE/src/Cache/Engine/FileEngine.php, line 303
Cake\Cache\Engine\FileEngine::clear() - CORE/src/Cache/Engine/FileEngine.php, line 284
Cake\Cache\Engine\FileEngine::gc() - CORE/src/Cache/Engine/FileEngine.php, line 116
Cake\Cache\CacheRegistry::_create() - CORE/src/Cache/CacheRegistry.php, line 98
Cake\Core\ObjectRegistry::load() - CORE/src/Core/ObjectRegistry.php, line 96
DebugKit\Cache\Engine\DebugEngine::init() - ROOT/vendor/cakephp/debug_kit/src/Cache/Engine/DebugEngine.php, line 79
Cake\Cache\CacheRegistry::_create() - CORE/src/Cache/CacheRegistry.php, line 90
Cake\Core\ObjectRegistry::load() - CORE/src/Core/ObjectRegistry.php, line 96
Cake\Cache\Cache::_buildEngine() - CORE/src/Cache/Cache.php, line 170
Cake\Cache\Cache::engine() - CORE/src/Cache/Cache.php, line 228
Cake\Cache\Cache::read() - CORE/src/Cache/Cache.php, line 356
App\Controller\AppController::beforeRender() - APP/Controller/AppController.php, line 169
Cake\Event\EventManager::_callListener() - CORE/src/Event/EventManager.php, line 416
Cake\Event\EventManager::dispatch() - CORE/src/Event/EventManager.php, line 393
Cake\Controller\Controller::dispatchEvent() - CORE/src/Event/EventDispatcherTrait.php, line 110
Cake\Controller\Controller::render() - CORE/src/Controller/Controller.php, line 610
Cake\Http\ActionDispatcher::_invoke() - CORE/src/Http/ActionDispatcher.php, line 125
Cake\Http\ActionDispatcher::dispatch() - CORE/src/Http/ActionDispatcher.php, line 93
Cake\Http\BaseApplication::__invoke() - CORE/src/Http/BaseApplication.php, line 108
Cake\Http\Runner::__invoke() - CORE/src/Http/Runner.php, line 65
Cake\Http\Middleware\EncryptedCookieMiddleware::__invoke() - CORE/src/Http/Middleware/EncryptedCookieMiddleware.php, line 89
Cake\Http\Runner::__invoke() - CORE/src/Http/Runner.php, line 65
Cake\Http\Middleware\CsrfProtectionMiddleware::__invoke() - CORE/src/Http/Middleware/CsrfProtectionMiddleware.php, line 106
App\Application::App\{closure}() - APP/Application.php, line 93
Cake\Http\Runner::__invoke() - CORE/src/Http/Runner.php, line 65
Cake\Http\Middleware\SecurityHeadersMiddleware::__invoke() - CORE/src/Http/Middleware/SecurityHeadersMiddleware.php, line 176
Cake\Http\Runner::__invoke() - CORE/src/Http/Runner.php, line 65
Cake\Routing\Middleware\RoutingMiddleware::__invoke() - CORE/src/Routing/Middleware/RoutingMiddleware.php, line 104
Cake\Http\Runner::__invoke() - CORE/src/Http/Runner.php, line 65
Cake\Routing\Middleware\AssetMiddleware::__invoke() - CORE/src/Routing/Middleware/AssetMiddleware.php, line 88
Cake\Http\Runner::__invoke() - CORE/src/Http/Runner.php, line 65
Cake\Error\Middleware\ErrorHandlerMiddleware::__invoke() - CORE/src/Error/Middleware/ErrorHandlerMiddleware.php, line 98
Cake\Http\Runner::__invoke() - CORE/src/Http/Runner.php, line 65
Cake\Http\Middleware\EncryptedCookieMiddleware::__invoke() - CORE/src/Http/Middleware/EncryptedCookieMiddleware.php, line 89
Cake\Http\Runner::__invoke() - CORE/src/Http/Runner.php, line 65
DebugKit\Middleware\DebugKitMiddleware::__invoke() - ROOT/vendor/cakephp/debug_kit/src/Middleware/DebugKitMiddleware.php, line 52
Cake\Http\Runner::__invoke() - CORE/src/Http/Runner.php, line 65
Cake\Http\Runner::run() - CORE/src/Http/Runner.php, line 51
Cake\Http\Server::run() - CORE/src/Http/Server.php, line 81
[main] - ROOT/webroot/index.php, line 40

如有任何提示,我将不胜感激。

感谢@ndm,我能够找到这种行为的原因和解决方案。它发生在某些条件下的流量原因 - 多个请求将文件放入删除队列,并且在第一个请求删除文件后其他请求失败 - getRealPath() returns false 然后附加 / 所以结果路径是 /.

如果没有适当的 basedir 限制,最坏的情况(引用@ndm): 网络服务器用户有权删除/(通常应为none)中的所有文件都将被删除

方案一(推荐): 使用补丁 3.9.7 或 4.2.4

更新您的 Cake 应用程序

方案二: 手动修复代码以检查 getRealPath() 不会 return false