Every CVE Search/ Get API key

CVE-2026-57584

Phalcon: Catastrophic backtracking (ReDoS) in the default Phalcon Router route lead to remote unauthenticated DoS

8.7 HighFix available

Phalcon is a high-performance, full-stack PHP framework. Prior to 5.15.0, every Phalcon MVC application built with a default router registers a built-in route whose compiled PCRE pattern contains the nested quantifier (/.), and the same construct is produced by the /:params placeholder and the CLI router. Phalcon\Mvc\Router::handle() matches this pattern against the attacker-controlled request URI on every request, so a crafted path such as one containing repeated slashes followed by decoded newlines can trigger catastrophic backtracking and cause CPU exhaustion or route-matching failure. This issue is fixed in version 5.15.0.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
None
User interaction
None

What an attacker can affect

Confidentiality
None
Integrity
None
Availability
High

Exploit likelihood

0.53%Up 0.1 points since Jul 11, 2026
90%50%10%1%

What each source reports

CVE List Score used 8.7

Phalcon: Catastrophic backtracking (ReDoS) in the default Phalcon Router route lead to remote unauthenticated DoS

Phalcon is a high-performance, full-stack PHP framework. Prior to 5.15.0, every Phalcon MVC application built with a default router registers a built-in route whose compiled PCRE pattern contains the nested quantifier (/.), and the same construct is produced by the /:params placeholder and the CLI router. Phalcon\Mvc\Router::handle() matches this pattern against the attacker-controlled request URI on every request, so a crafted path such as one containing repeated slashes followed by decoded newlines can trigger catastrophic backtracking and cause CPU exhaustion or route-matching failure. This issue is fixed in version 5.15.0.

Record
CVE-2026-57584
CVSS 4.0
8.7 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
Weakness
CWE-1333
Updated
2026-11-02
EUVDEUVD-2026-43098 8.7

Phalcon is a high-performance, full-stack PHP framework. Prior to 5.15.0, every Phalcon MVC application built with a default router registers a built-in route whose compiled PCRE pattern contains the nested quantifier (/.), and the same construct is produced by the /:params placeholder and the CLI router. Phalcon\Mvc\Router::handle() matches this pattern against the attacker-controlled request URI on every request, so a crafted path such as one containing repeated slashes followed by decoded newlines can trigger catastrophic backtracking and cause CPU exhaustion or route-matching failure. This issue is fixed in version 5.15.0.

Record
EUVD-2026-43098
CVSS 4.0
8.7 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-x7rj-f32v-7jjg 8.7

Phalcon: Catastrophic backtracking (ReDoS) in the default Phalcon Router route lead to remote unauthenticated DoS

Summary

Every Phalcon MVC application built with a default router (new Phalcon\Mvc\Router() or new Phalcon\Mvc\Router(true), which is the normal case) registers a built-in route whose compiled PCRE pattern is #^/([\w0-9\_\-]+)/([\w0-9\.\_]+)(/.*)*$#u. The trailing (/.*)* is a nested quantifier whose group body (/.*) overlaps itself (. matches /, and there is no s/DOTALL flag), so when the final $ is forced to fail the engine explores roughly 2^(N/2) ways to split a run of N slashes, causing classic catastrophic backtracking. Phalcon\Mvc\Router::handle() runs on every request and matches this pattern against the attacker-controlled request URI, so a single short request can burn seconds-to-minutes of CPU per request. The same (/.*)* construct is also produced by the /:params placeholder (Phalcon\Mvc\Router\Route::compilePattern()) and by the CLI router (Phalcon\Cli\Router / Phalcon\Cli\Router\Route).

Details

The vulnerable pattern is emitted in four places, all carrying the same * nested quantifier:

  • Default MVC route registration phalcon/Mvc/Router.zep (Router::__construct()): "#^/([\\w0-9\\_\\-]+)/([\\w0-9\\.\\_]+)(/.*)*$#u", with paths ["controller": 1, "action": 2, "params": 3].
  • /:params placeholder expansions phalcon/Mvc/Router/Route.zep (Route::compilePattern()): str_replace("/:params", "(/.*)*", pattern).
  • Default CLI route phalcon/Cli/Router.zep (Router::__construct()): "#^(?::delimiter)?([a-zA-Z0-9\\_\\-]+):delimiter([a-zA-Z0-9\\.\\_]+)(:delimiter.*)*$#".
  • CLI /:params expansion phalcon/Cli/Router/Route.zep (Route::compilePattern()): "(" . this->delimiter . ".*)*".

Router::handle() matches the request URI against this pattern on every request (the combined-regex fast path and the per-route dynamic loop both call preg_match() with it). When the subject string ends in a byte that the group cannot consume (for example a newline, since . does not match \n), the anchored $ cannot be satisfied and the engine backtracks over every partition of the leading run of slashes, which is exponential in the number of slashes.

Remote reachability

In the default MVC configuration the router uses URI_SOURCE_GET_URL, i.e. it reads the request path from $_GET["_url"], which the web server populates from the rewritten request path. PHP URL-decodes $_GET, so a request path containing %0a%0a arrives as the literal two-byte string "\n\n". The two newlines are the trigger: . cannot match \n, and PCRE's $ forgives exactly one trailing \n, so two of them force the match to fail and unleash the backtracking. No authentication, cookies, or application-specific routes are needed.

Example malicious request path (≈40 bytes): /a/a////////////////////////////////%0a%0a (two short segments, a run of /, then %0a%0a).

Applications configured with URI_SOURCE_SERVER_REQUEST_URI are not reachable through this specific newline trick because REQUEST_URI is not URL-decoded; they remain exposed to the underlying CPU amplification when the unmatchable tail can be introduced by other means.

Proof of Concept

<?php

use Phalcon\Di\FactoryDefault;
use Phalcon\Mvc\Router;

$di = new FactoryDefault();
$router = new Router(true);   // defaultRoutes = true (the default)
$router->setDI($di);

echo "phalcon            : " . phpversion("phalcon") . "\n";
echo "pcre.backtrack_limit: " . ini_get("pcre.backtrack_limit") . "\n";
echo "pcre.jit           : " . ini_get("pcre.jit") . "\n";

// Default configuration
foreach ($router->getRoutes() as $r) {
    if (strpos($r->getCompiledPattern(), "(/.*)*") !== false) {
        echo "vulnerable route   : " . $r->getCompiledPattern() . "\n";
    }
}
echo "\n";

function bench(Router $router, string $uri, string $label): void
{
    $t0 = hrtime(true);
    try {
        $router->handle($uri);
    } catch (\Throwable $e) {
        // matching failure and fallback to time
    }
    $ms =…
Record
GHSA-x7rj-f32v-7jjg
CVSS 4.0
8.7 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
Weakness
CWE-1333
Updated
2026-11-02
NVD 8.7

Phalcon is a high-performance, full-stack PHP framework. Prior to 5.15.0, every Phalcon MVC application built with a default router registers a built-in route whose compiled PCRE pattern contains the nested quantifier (/.), and the same construct is produced by the /:params placeholder and the CLI router. Phalcon\Mvc\Router::handle() matches this pattern against the attacker-controlled request URI on every request, so a crafted path such as one containing repeated slashes followed by decoded newlines can trigger catastrophic backtracking and cause CPU exhaustion or route-matching failure. This issue is fixed in version 5.15.0.

Record
CVE-2026-57584
CVSS 4.0
8.7 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
Weakness
CWE-1333
Updated
2026-11-02
OSV 8.7

Phalcon: Catastrophic backtracking (ReDoS) in the default Phalcon Router route lead to remote unauthenticated DoS

Phalcon is a high-performance, full-stack PHP framework. Prior to 5.15.0, every Phalcon MVC application built with a default router registers a built-in route whose compiled PCRE pattern contains the nested quantifier (/.), and the same construct is produced by the /:params placeholder and the CLI router. Phalcon\Mvc\Router::handle() matches this pattern against the attacker-controlled request URI on every request, so a crafted path such as one containing repeated slashes followed by decoded newlines can trigger catastrophic backtracking and cause CPU exhaustion or route-matching failure. This issue is fixed in version 5.15.0.

Record
CVE-2026-57584
CVSS 4.0
8.7 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
Weakness
CWE-1333
Updated
2026-11-02
OSVGHSA-x7rj-f32v-7jjg 8.7

Phalcon: Catastrophic backtracking (ReDoS) in the default Phalcon Router route lead to remote unauthenticated DoS

Summary

Every Phalcon MVC application built with a default router (new Phalcon\Mvc\Router() or new Phalcon\Mvc\Router(true), which is the normal case) registers a built-in route whose compiled PCRE pattern is #^/([\w0-9\_\-]+)/([\w0-9\.\_]+)(/.*)*$#u. The trailing (/.*)* is a nested quantifier whose group body (/.*) overlaps itself (. matches /, and there is no s/DOTALL flag), so when the final $ is forced to fail the engine explores roughly 2^(N/2) ways to split a run of N slashes, causing classic catastrophic backtracking. Phalcon\Mvc\Router::handle() runs on every request and matches this pattern against the attacker-controlled request URI, so a single short request can burn seconds-to-minutes of CPU per request. The same (/.*)* construct is also produced by the /:params placeholder (Phalcon\Mvc\Router\Route::compilePattern()) and by the CLI router (Phalcon\Cli\Router / Phalcon\Cli\Router\Route).

Details

The vulnerable pattern is emitted in four places, all carrying the same * nested quantifier:

  • Default MVC route registration phalcon/Mvc/Router.zep (Router::__construct()): "#^/([\\w0-9\\_\\-]+)/([\\w0-9\\.\\_]+)(/.*)*$#u", with paths ["controller": 1, "action": 2, "params": 3].
  • /:params placeholder expansions phalcon/Mvc/Router/Route.zep (Route::compilePattern()): str_replace("/:params", "(/.*)*", pattern).
  • Default CLI route phalcon/Cli/Router.zep (Router::__construct()): "#^(?::delimiter)?([a-zA-Z0-9\\_\\-]+):delimiter([a-zA-Z0-9\\.\\_]+)(:delimiter.*)*$#".
  • CLI /:params expansion phalcon/Cli/Router/Route.zep (Route::compilePattern()): "(" . this->delimiter . ".*)*".

Router::handle() matches the request URI against this pattern on every request (the combined-regex fast path and the per-route dynamic loop both call preg_match() with it). When the subject string ends in a byte that the group cannot consume (for example a newline, since . does not match \n), the anchored $ cannot be satisfied and the engine backtracks over every partition of the leading run of slashes, which is exponential in the number of slashes.

Remote reachability

In the default MVC configuration the router uses URI_SOURCE_GET_URL, i.e. it reads the request path from $_GET["_url"], which the web server populates from the rewritten request path. PHP URL-decodes $_GET, so a request path containing %0a%0a arrives as the literal two-byte string "\n\n". The two newlines are the trigger: . cannot match \n, and PCRE's $ forgives exactly one trailing \n, so two of them force the match to fail and unleash the backtracking. No authentication, cookies, or application-specific routes are needed.

Example malicious request path (≈40 bytes): /a/a////////////////////////////////%0a%0a (two short segments, a run of /, then %0a%0a).

Applications configured with URI_SOURCE_SERVER_REQUEST_URI are not reachable through this specific newline trick because REQUEST_URI is not URL-decoded; they remain exposed to the underlying CPU amplification when the unmatchable tail can be introduced by other means.

Proof of Concept

<?php

use Phalcon\Di\FactoryDefault;
use Phalcon\Mvc\Router;

$di = new FactoryDefault();
$router = new Router(true);   // defaultRoutes = true (the default)
$router->setDI($di);

echo "phalcon            : " . phpversion("phalcon") . "\n";
echo "pcre.backtrack_limit: " . ini_get("pcre.backtrack_limit") . "\n";
echo "pcre.jit           : " . ini_get("pcre.jit") . "\n";

// Default configuration
foreach ($router->getRoutes() as $r) {
    if (strpos($r->getCompiledPattern(), "(/.*)*") !== false) {
        echo "vulnerable route   : " . $r->getCompiledPattern() . "\n";
    }
}
echo "\n";

function bench(Router $router, string $uri, string $label): void
{
    $t0 = hrtime(true);
    try {
        $router->handle($uri);
    } catch (\Throwable $e) {
        // matching failure and fallback to time
    }
    $ms =…
Record
GHSA-x7rj-f32v-7jjg
CVSS 4.0
8.7 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
Weakness
CWE-1333
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
phalcon/cphalcon
Packagist
through 5.14.2
5.15.0
phalcon/cphalcon
Packagist
before 5.15.0, plus listed versions
5.10.05.12.05.9.05.9.15.9.2
Show 45 moreShow less
5.9.3v3.0.0v3.0.1v3.0.2v3.0.3v3.0.4v3.1.0v3.1.0-alpha1v3.1.0-alpha2v3.1.1v3.1.2v3.2.0v3.2.1v3.2.2v3.2.3v3.2.4v3.3.0v3.3.1v3.3.2v3.4.0v3.4.1v3.4.2v3.4.3v3.4.4v3.4.5v4.0.0v4.0.0-alpha.2v4.0.0-alpha.3v4.0.0-alpha.4v4.0.0-alpha.5v4.0.0-alpha1v4.0.0-beta.1v4.0.0-beta.2v4.0.0-rc.1v4.0.0-rc.2v4.0.0-rc.3v4.0.1v4.0.2v4.0.3v4.0.4v4.0.5v4.0.6v4.1.0v4.1.1v4.1.2
5.15.0

History

History
RecordedChangedSources
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-57584 is a high vulnerability (CVSS 8.7) in Phalcon Cphalcon, published July 10, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.53%, the 45th percentile. Fixed in phalcon/cphalcon 5.15.0.

References

This page doesn't list everything

Left out here: 46 versions and the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open