CVE-2026-54133: jmespath.php CompilerRuntime Code Injection via Unescaped Function Names
A flaw in jmespath.php's compiler runtime lets an attacker smuggle arbitrary PHP code into a cached file by crafting a JMESPath expression that uses a raw string or literal as a function name, which…

The problem
In jmespath.php before 2.9.1, the CompilerRuntime compiles JMESPath expressions to PHP source and writes that source to a cache directory on disk. When generating a function call, the compiler emits the parsed function name token directly into the PHP source without safely escaping it as a string literal.
The JMESPath parser accepted non-identifier tokens (raw string literals delimited by single quotes, and backtick-delimited JSON literals) in the function-callee position. An attacker who can control the JMESPath expression string can embed a crafted raw string there to break out of the generated PHP string context and inject arbitrary PHP.
That generated file is then loaded and executed by CompilerRuntime, giving the attacker full code execution with the privileges of the PHP process.
Proof of concept
A working proof-of-concept for CVE-2026-54133 in mtdowling/jmespath.php, with the exact payload below.
'foo').system($_GET["cmd"]).array(
foo
)The exploit places a raw string literal (single-quote delimited) where the parser expects a function name. Before the fix, the parser accepted this without error. The compiler then wrote the raw string value into generated PHP source as if it were a safe identifier, without calling var_export() or any other escaping.
The injected value closes the surrounding PHP string context (with the closing parenthesis and period), appends a system() call with attacker-controlled input, then reopens the string context so the rest of the generated code remains syntactically valid. The resulting cache file contains live PHP that executes on the next require.
The patch takes two complementary steps: it makes the parser reject any non-identifier token in the function-callee position (so the malformed expression is now a parse error), and it wraps any function name that reaches code generation in var_export() so even a valid identifier cannot be used to inject code.
CWE-94 (Code Injection) and CWE-116 (Improper Output Escaping) both apply here.
The fix
Upgrade to composer package mtdowling/jmespath.php version 2.9.1 or later. If an immediate upgrade is not possible, disable JP_PHP_COMPILE and do not instantiate JmesPath\CompilerRuntime with user-controlled expressions. The default JmesPath\AstRuntime (used by JmesPath\search() when JP_PHP_COMPILE is not set) interprets the AST in memory and is not affected by this vulnerability.
Reported by edorian.
Related research
- high · 8.5CVE-2026-55072CVE-2026-55072: Pimcore ClassDefinition UID Regex Missing End Anchor Allows SQL Injection
- critical · 9.8CVE-2026-52778CVE-2026-52778: YesWiki CalcField Unsafe eval() Remote Code Execution and ReDoS
- highCVE-2026-56382: Craft CMS RCE via Yii2 Event Handler Injection in FieldsController
- criticalCVE-2026-27823CVE-2026-27823: EGroupware SmallPART Remote Code Execution via Auth Bypass and Path Traversal