Aug 26, 2026·7 min read·1 visit
An unsafe reflection flaw in CakePHP's DebugKit toolbar allows remote attackers to instantiate arbitrary PHP classes, potentially triggering remote code execution, database interactions, or denial of service through destructor/constructor side-effects.
CVE-2026-54614 is an unsafe reflection vulnerability in the MailPreview component of cakephp/debug_kit prior to versions 4.10.3 and 5.2.4. Unauthenticated or low-privileged remote attackers can exploit this vulnerability to dynamically resolve and instantiate arbitrary PHP classes within the Composer autoloader environment, leading to constructor and destructor execution.
The cakephp/debug_kit package provides a debugging toolbar containing various panels designed to simplify development. Among these is the MailPreview panel, which allows developers to test and view simulated email templates sent by the application. This feature exposes routes that dynamically process class and method names via user input in order to find, load, and render email previews.
The dynamic resolution relies on resolving class strings dynamically from URL routing parameters. Under normal operations, the toolbar expects to receive a simple name corresponding to a defined MailPreview subclass. It then resolves this name to a class inside the Mailer/Preview directory structure. However, because the routing logic does not enforce a rigorous strict-type or namespace boundary check, an attacker can specify arbitrary PHP namespaces in the URL path.
This behavior exposes the application to unsafe reflection (CWE-470). An attacker capable of sending network requests to the DebugKit routes can bypass local namespace assumptions. By doing so, they can force the application to instantiate any autoloadable PHP class available in the environment, utilizing constructor side-effects to achieve execution.
The root cause of the vulnerability lies within the class resolution method inside src/Controller/MailPreviewController.php. The controller relies on the App::className() utility method provided by the core CakePHP framework to convert shorthand class names into fully qualified namespaces.
The App::className() utility expects class names to match structured conventions. However, if the input parameter contains backslashes (e.g., Cake\Utility\Inflector), App::className() assumes that the input represents an absolute fully qualified class name. It bypasses conventional namespace prefixing logic and returns the class path as-is, provided the class is resolvable within the Composer autoloader.
Following class resolution, the application performs direct instantiation via new $realClass(). Crucially, before the patch, the application failed to verify whether the resolved class implements the expected base class or interface. It assumed any resolved class was an authorized mailer preview class.
Furthermore, the controller attempts to invoke the user-controlled $emailName method on the newly instantiated object. Even if the method call fails or throws an exception (due to incompatible signatures or non-existent methods), the object remains instantiated in memory. When the PHP engine initiates garbage collection at the end of the request-response lifecycle, the target class's destructor (__destruct()) is triggered. This behavior allows attackers to execute arbitrary destructors, enabling standard PHP destructor-based gadget chain exploitation.
To understand the vulnerability's mechanics, we can inspect the difference between the vulnerable implementation and the patched version in src/Controller/MailPreviewController.php.
Below is the vulnerable implementation:
protected function findPreview($previewName, $emailName, $plugin = '')
{
if ($plugin) {
$plugin = "$plugin.";
}
// Resolves input directly. If $previewName has backslashes, it bypasses Mailer/Preview structure.
$realClass = App::className($plugin . $previewName, 'Mailer/Preview');
if (!$realClass) {
throw new NotFoundException("Mailer preview ${previewName} not found");
}
// Vulnerable: Instantiation happens without validation.
$mailPreview = new $realClass();
...
}The official patch restricts resolved names to block namespace navigation and validates inheritance prior to instantiation:
protected function findPreview($previewName, $emailName, $plugin = null)
{
if ($plugin) {
$plugin = "$plugin.";
}
// 1. Explicitly block backslashes to prevent namespace bypassing
if (str_contains($previewName, '\\')) {
throw new NotFoundException("Mailer preview $previewName not found");
}
$realClass = App::className($plugin . $previewName, 'Mailer/Preview');
// 2. Validate that the class is a subclass of MailPreview before instantiation
if (!$realClass || !is_subclass_of($realClass, MailPreview::class, true)) {
throw new NotFoundException("Mailer preview ${previewName} not found");
}
// Safe: The object is guaranteed to be a valid MailPreview instance
$mailPreview = new $realClass();
...
}The check using is_subclass_of with the third parameter set to true is critical. It evaluates the string name of the class without instantiating it first, preventing the constructor from executing prematurely. By combining this with the backslash restriction, the vulnerability is fully mitigated.
Exploitation of CVE-2026-54614 requires access to the DebugKit interface, which is typically enabled only in development environments. However, production environments with misconfigured environments can also be targeted. No authentication is typically needed to interact with the DebugKit routing namespace if the host header checks are bypassed or the server is public-facing.
An attacker can trigger the vulnerability by sending a standard HTTP GET request. The input is passed directly in the URL structure. For example, testing for structural vulnerability can be achieved by supplying a known core CakePHP utility class like Cake\Utility\Inflector:
GET /debug-kit/mail-preview/preview/Cake%5CUtility%5CInflector/slug HTTP/1.1
Host: target-app.local
Accept: text/htmlIf the application is vulnerable, the server will attempt to locate Cake\Utility\Inflector via the autoloader, instantiate it, and execute its constructor. If the application has been patched, the request immediately terminates with a 404 Not Found response because of the backslash validation rule.
To escalate this vulnerability beyond simple resource loading, an attacker must identify classes with sensitive behavior inside their constructors or destructors. In modern PHP frameworks, such gadget chains are common in third-party vendor libraries (e.g., Monolog, Guzzle, or Doctrine). For example, if a loaded class contains a destructor that writes or deletes a temporary file based on instance variables, triggering its instantiation can lead to arbitrary file modification or destruction on the host system.
The baseline CVSS score for this vulnerability is 4.3 (Medium), with a vector of CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N. This calculation assumes a scenario where the impact is limited to low confidentiality disclosure through execution of basic methods. However, in practice, the operational impact can be significantly higher.
If a compatible gadget chain is present inside the application's dependencies (such as classes in the /vendor directory), the threat shifts from local information disclosure to complete system compromise. This allows an attacker to achieve Remote Code Execution (RCE) or arbitrary file delete actions.
Because DebugKit is a standard dependency in the CakePHP ecosystem, many web applications retain it in their composer files. If a developer accidentally deploys a container with the development configuration enabled (e.g., debug mode set to true), the attack vector becomes immediately reachable over the internet.
The definitive solution is to upgrade cakephp/debug_kit to version 4.10.3 (for CakePHP 4.x applications) or 5.2.4 (for CakePHP 5.x applications) using Composer. These updates contain the namespace containment logic and subclass validation routines.
In addition to upgrading, organizations must apply robust defense-in-depth measures. Development dependencies such as DebugKit must never be loaded in production environments. Developers should ensure that their composer.json file separates development tools into the require-dev block, and deployments must be executed using the --no-dev parameter:
composer install --no-dev --optimize-autoloaderFurthermore, ensure that the core CakePHP configuration has debugging disabled in all production and staging environments:
// config/app.php or config/app_local.php
'debug' => false,To detect potential exploitation attempts at the network layer, Web Application Firewalls (WAFs) should be configured to block requests to the MailPreview controller containing backslashes. For example, a custom detection regex pattern can target paths matching /debug-kit/mail-preview/ that contain %5C or raw backslash sequences.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
debug_kit cakephp | < 4.10.3 | 4.10.3 |
debug_kit cakephp | >= 5.0.0, < 5.2.4 | 5.2.4 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-470 |
| Attack Vector | Network |
| CVSS v3.1 | 4.3 (Medium) |
| Exploit Status | poc |
| KEV Status | Not Listed |
| Impact | Unsafe Reflection / Arbitrary Class Instantiation / Potential Remote Code Execution |
The application uses input from an external source to determine which class to instantiate or which method to execute, without verifying that the class or method is authorized.
A Stored Cross-Site Scripting (XSS) vulnerability exists within the legacy presentation templates of the LibreNMS network monitoring system. Due to inadequate context-aware output encoding of operational data ingested via Simple Network Management Protocol (SNMP) polling, Border Gateway Protocol (BGP) notifications, and incoming Syslog messages, an administrative user viewing device dashboards can be targeted with arbitrary JavaScript execution.
An incomplete input sanitization fix in AsyncSSH version 2.23.0 allows unauthenticated remote attackers to bypass directory restriction controls and perform path-traversal attacks. When the system is configured to perform username token substitution inside its AuthorizedKeysFile directive, attackers can manipulate downstream path resolution mechanisms via tilde expansion and environment variable references. This flaw permits authentication bypasses by forcing the server to read public keys from unauthorized file locations outside the restricted environment.
CVE-2026-54591 is a high-severity path traversal vulnerability in AsyncSSH's SCP implementation prior to version 2.23.1. When an AsyncSSH-based SCP client connects to a malicious or compromised SSH server and performs a file transfer, the server can send crafted filenames containing relative path sequences. Because the client failed to validate these filenames before resolving the final storage path, a malicious server could write or overwrite arbitrary files on the client machine within the security context of the executing application. This vulnerability is mapped to GitHub Security Advisory GHSA-2wxc-x7rj-hg8f.
An unrestricted file upload vulnerability exists in the Pollen Robotics Reachy Mini robot daemon prior to version 1.8.2. Unauthenticated remote attackers can upload arbitrary files to the temporary sounds directory over the network, leading to disk pollution and staging for potential secondary local exploits.
CVE-2026-55637 is a high-severity DNS rebinding vulnerability affecting the genieacs-mcp Model Context Protocol server. Prior to version 0.3.2, the application's Streamable HTTP transport lacks adequate Host and Origin header validation. This omission allows external attackers to bypass the Same-Origin Policy through a victim's browser and issue unauthenticated commands to loopback listeners.
A critical vulnerability exists in the elixir-grpc library's Erlpack codec, where the unsafe deserialization of Erlang External Term Format (ETF) payloads allows unauthenticated remote attackers to cause a Denial of Service through atom table exhaustion or execute arbitrary code on the host server.