Skip to content

fix(Cache): reject directory traversal sequences and separators in FileHandler::validateKey() - #10766

Open
gr8man wants to merge 1 commit into
codeigniter4:developfrom
gr8man:fix/cache-filehandler-validatekey-traversal
Open

gr8man wants to merge 1 commit into
codeigniter4:developfrom
gr8man:fix/cache-filehandler-validatekey-traversal

Conversation

@gr8man

@gr8man gr8man commented Nov 11, 2026

Copy link
Copy Markdown
Contributor

Description

FileHandler builds the path of a cache item by appending the validated key to the cache store path:

$this->path . $key

BaseHandler::validateKey() rejects /, \ and .. only indirectly, through Config\Cache::$reservedCharacters. That setting is often emptied when a single key namespace is shared by several handlers (for example file storage alongside Redis/Memcached), and in that case a key such as ../foo or sub/key reaches the file system unchanged, allowing a write/read/unlink outside the cache directory (path traversal).

This PR makes the file handler's own validation authoritative, independently of $reservedCharacters:

  • FileHandler::validateKey() now rejects /, \, the null byte, and traversal sequences (..) in both the key and the prefix, and throws CodeIgniter\Exceptions\InvalidArgumentException.
  • Valid keys keep the existing behaviour: PSR-6 checks from BaseHandler::validateKey() (string type, non-empty, configured reserved characters) and MD5 hashing when the prefixed key exceeds MAX_KEY_LENGTH.
  • Regression tests cover traversal with and without separators, both separators, a null byte, a traversal sequence in the prefix, and a valid key; the test restores reservedCharacters so it does not leak state into other tests.

Fixes the traversal vector without requiring applications to configure reservedCharacters.

Checklist:

  • Securely signed commits
  • Component(s) with PHPDoc blocks, only if necessary or adds value (without duplication)
  • Unit testing, with >80% coverage
  • User guide updated
  • Conforms to style guide

…leHandler::validateKey()

The file handler concatenates the cache key with the cache store path, so a
key that contains a directory separator or a traversal sequence can address
files outside the cache directory. BaseHandler::validateKey() only rejects
such characters when Config\Cache::$reservedCharacters happens to contain
them, and that setting is commonly emptied when several handlers share the
same keys (for example file storage next to Redis).

FileHandler::validateKey() now always rejects "/", "\", a null byte, and
traversal sequences ("..") in both the key and the prefix, independently of
the configured reservedCharacters, throwing
CodeIgniter\Exceptions\InvalidArgumentException. Valid keys keep the
existing PSR-6 validation and hashing behaviour.
@carson-codeigniter4 carson-codeigniter4 Bot added the bug Verified issues on the current code behavior or pull requests that will fix them label Nov 11, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Verified issues on the current code behavior or pull requests that will fix them

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant