User tests: Successful: Unsuccessful:
This PR adds allowed_classes => false to all unserialize() calls in the four cache controller get() methods.
The following files call unserialize() without restricting which PHP classes can be instantiated during deserialization:
libraries/src/Cache/Controller/OutputController.phplibraries/src/Cache/Controller/PageController.phplibraries/src/Cache/Controller/ViewController.phplibraries/src/Cache/Controller/CallbackController.phpIf the cache backend (filesystem, Memcached, Redis, APCu) is accessible to an attacker — either through a poisoned cache entry, a compromised cache server, or a path traversal in the file cache — they can inject a serialized PHP object that will be instantiated during unserialize(). This can trigger __wakeup() / __destruct() magic methods on any class loaded in memory, potentially leading to Remote Code Execution (PHP Object Injection, CWE-502).
Pass ['allowed_classes' => false] as the second argument to unserialize(). This is safe because:
OutputController: data is always a plain PHP value (string/array), never an objectPageController: data is always a structured array of strings (body, head, pathway, modules) — verified by reviewing Cache::setWorkarounds()ViewController: data is always a string (rendered view output)CallbackController: data is always ['output' => string, 'result' => mixed] — no objectsWhen allowed_classes => false, unserialize() will return false instead of instantiating a malicious object, preventing the gadget chain from executing.
Code analysis confirms that in all four controllers, the store() method serializes only arrays of scalars or strings. No PHP object instances are ever stored. Therefore allowed_classes => false cannot cause a regression.
| Status | New | ⇒ | Pending |
| Category | ⇒ | Libraries |
| Status | Pending | ⇒ | Closed |
| Closed_Date | 0000-00-00 00:00:00 | ⇒ | 2026-05-31 02:27:10 |
| Closed_By | ⇒ | XananasX7 | |
| Labels |
Added:
PR-5.4-dev
|
||
Summary for reviewers:
This PR adds
['allowed_classes' => false]to the four cache controllerunserialize()calls (CallbackController,OutputController,PageController,ViewController).Why
allowed_classes => falseis safe here:The cache layer stores serialized PHP values (strings, arrays, numbers) — not serialized objects. The Joomla cache is designed around data caching, not object persistence. Restricting deserialization to non-object types removes any risk of PHP Object Injection via a poisoned cache backend (e.g. Redis/Memcache compromise, or a file cache with predictable paths accessible to an attacker).
This is a defense-in-depth hardening aligned with PHP's security recommendation for unserializing data from potentially attacker-influenced storage.
No functional behavior change for any normal Joomla usage.