CVE-2026-54736: Phalcon Non-constant-time HMAC Verification Vulnerability
HIGHCVE-2026-54736 is a HIGH non-constant-time hmac verification vulnerability (CWE-208: Observable Timing Discrepancy) affecting Phalcon libraries in the Packagist ecosystem. The issue involves non-constant-time hmac verification in `encryption\crypt::decrypt` (timing side-channel). Remediation is available by upgrading affected packages to version 5.14.1.
CVE-2026-54736 at a Glance
How to Fix CVE-2026-54736
To remediate this vulnerability, upgrade all affected Phalcon dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.
Upgrade phalcon/cphalcon to 5.14.1
Run the following command in your project directory to verify that all resolved dependencies use the patched release:
inspect dependencies for phalcon/cphalcon
How to Check if You Are Affected
To determine whether your application is affected by CVE-2026-54736, inspect your project dependencies for Phalcon:
inspect dependencies for phalcon/cphalcon
Analyze the terminal output to locate any version of Phalcon in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 5.14.1), your application is affected.
Note: Verify declared build manifests and deployed runtime container environments.
Technical Details
Vulnerability Mechanism & Technical Analysis
This vulnerability is classified under CWE-208: Observable Timing Discrepancy, where two separate operations in a product require different amounts of time to complete, in a way that is observable to an actor and reveals security-relevant information about the state of the product, such as whether a particular operation was successful or not. In Phalcon, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.
Source Advisory Statement
CVE-2026-54736 Affected Phalcon Versions
1 component(s)| Product / Package | Ecosystem | Affected Versions | Fixed Version |
|---|---|---|---|
|
phalcon/cphalcon
|
Packagist |
< 5.14.1
|
5.14.1
|
References
Frequently Asked Questions
What is CVE-2026-54736?
Which Phalcon versions are affected?
What version fixes CVE-2026-54736?
Is phalcon/cphalcon affected?
What CWE is associated with CVE-2026-54736?
How can I check Packagist dependencies for CVE-2026-54736?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-8jqh-95g6-7jpj",
"modified" : "2026-08-28T16:01:05Z",
"published" : "2026-08-28T16:01:05Z",
"aliases" : [ "CVE-2026-54736" ],
"summary" : "Phalcon: Non-constant-time HMAC verification in `Encryption\\Crypt::decrypt` (timing side-channel)",
"details" : "## Summary\n\n`Phalcon\\Encryption\\Crypt` provides authenticated encryption: when `useSigning` is enabled (the default), `encrypt()` appends an HMAC tag and `decrypt()` verifies it before returning the plaintext. The verification compares the attacker-supplied tag against the freshly computed HMAC using PHP/Zephir identity comparison (`!==`), which the Zephir compiler lowers to `!ZEPHIR_IS_IDENTICAL(...)` — a byte-wise `memcmp` that returns early on the first differing byte. The comparison time therefore depends on how many leading bytes of the supplied tag are correct, a classic MAC-verification timing side-channel. Every other secret/MAC comparison in the framework uses the constant-time `hash_equals()` (`zephir_hash_equals`) — the CSRF token check (`Security::checkToken`) and the JWT signature check (`Signer\\Hmac::verify`); `Crypt::decrypt` is the lone deviation.\n\n## Details\n\n### Vulnerable code\n\n`phalcon/Encryption/Crypt.zep:246` (Zephir source):\n\n```zephir\nif true === this->useSigning {\n // Checks on the decrypted message digest using the HMAC method.\n if digest !== hash_hmac(hashAlgorithm, padded, decryptKey, true) {\n throw new Mismatch(\"Hash does not match.\");\n }\n}\n```\n\nGenerated C --> `ext/phalcon/encryption/crypt.zep.c:364-367`:\n\n```c\nZEPHIR_CALL_FUNCTION(&_8$$7, \"hash_hmac\", NULL, 245, &hashAlgorithm, &padded, &decryptKey, &__$true);\n...\nif (!ZEPHIR_IS_IDENTICAL(&digest, &_8$$7)) { // <-- non-constant-time\n ZEPHIR_THROW_EXCEPTION_DEBUG_STR(..., \"Hash does not match.\", \"phalcon/Encryption/Crypt.zep\", 247);\n```\n\n`ZEPHIR_IS_IDENTICAL` --> `zephir_is_identical()` (`ext/kernel/operators.c:472`) --> Zend `is_identical_function` --> for equal-length strings a `memcmp` that exits on the first mismatching byte (data-dependent timing).\n\n\n\n### Impact\n\nThe HMAC is the integrity/authentication tag of Phalcon's authenticated-encryption scheme. A successful timing attack (Keyczar/CVE-2009-0654-style: fix the IV+ciphertext so the target tag is constant, then recover it byte-by-byte from response timing) yields a tag the attacker can attach to a chosen IV+ciphertext so that `decrypt()` accepts it as authentic, defeating the integrity guarantee. Combined with CFB malleability (flipping a ciphertext byte flips the corresponding plaintext byte), an attacker who recovers the forging capability can tamper with the decrypted contents the application trusts (e.g. encrypted cookies carrying authorization/identity state). There is no confidentiality break by itself.\n\n## Suggested fix\n\nReplace the identity comparison with the constant-time helper already used elsewhere in the framework. In `phalcon/Encryption/Crypt.zep:246`:\n\n```zephir\n// before\nif digest !== hash_hmac(hashAlgorithm, padded, decryptKey, true) {\n throw new Mismatch(\"Hash does not match.\");\n}\n// after\nif true !== hash_equals(hash_hmac(hashAlgorithm, padded, decryptKey, true), digest) {\n throw new Mismatch(\"Hash does not match.\");\n}\n```\n\n`hash_equals()` returns false for unequal-length inputs, so it also covers the truncated-tag case. Optional further hardening: verify the MAC before unpadding (functionally moot here because `cryptUnpadText` never throws) and consider migrating the default toward an AEAD mode such as `aes-256-gcm`.\n\nAddressed Issue: \n\n- https://github.com/phalcon/cphalcon/issues/17090\n\nPatched Stream: \n\n- https://github.com/phalcon/cphalcon/issues/17090",
"severity" : [ {
"type" : "CVSS_V4",
"score" : "CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N"
} ],
"affected" : [ {
"package" : {
"ecosystem" : "Packagist",
"name" : "phalcon/cphalcon"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "0"
}, {
"fixed" : "5.14.1"
} ]
} ],
"database_specific" : {
"last_known_affected_version_range" : "<= 5.14.0"
}
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/phalcon/cphalcon/security/advisories/GHSA-8jqh-95g6-7jpj"
}, {
"type" : "ADVISORY",
"url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-54736"
}, {
"type" : "WEB",
"url" : "https://github.com/phalcon/cphalcon/issues/17090"
}, {
"type" : "WEB",
"url" : "https://github.com/phalcon/cphalcon/pull/17091"
}, {
"type" : "WEB",
"url" : "https://github.com/phalcon/cphalcon/commit/ad53ab1b2e7ec59b3af92b0b37b8aaa099011137"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/phalcon/cphalcon"
}, {
"type" : "WEB",
"url" : "https://github.com/phalcon/cphalcon/releases/tag/v5.14.1"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-208", "CWE-347" ],
"severity" : "HIGH",
"github_reviewed" : true,
"github_reviewed_at" : "2026-08-28T16:01:05Z",
"nvd_published_at" : "2026-07-10T22:16:42Z"
}
}