Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessControl dynamic partial lookup value
-
DeliveryPlace crafted AST object in template context
-
ExploitBypass resolvePartial() conditional guards
-
ExecutionTrigger invokePartial() to return undefined
-
PersistPass object to env.compile()
-
ImpactExecute arbitrary code via malicious AST
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A05:2025 - Injection
ASVS 5.0
V1 - Encoding and Sanitization Code injection prevention, sandbox exec
MITRE ATT&CK
2 techniques across 2 tactics: Execution, Initial Access The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up. |
| Exploitation Conditions | Attacker must control a value returned by dynamic partial lookup in Handlebars template context. Requires crafted object injection into template rendering pipeline. Remote unauthenticated exploitation possible if application exposes dynamic partial resolution to untrusted input. |
| Impact | The CVSS 3.1 vector (AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H) indicates network-accessible exploitation requiring no authentication but with high attack complexity due to specific prerequisites. Attack complexity arises from the need for both dynamic partial lookup syntax in templates and attacker control over context properties. No EPSS score or CISA KEV status provided in intelligence data; no public exploit identified at time of analysis beyond the documented proof-of-concept in the advisory. Real-world risk depends heavily on deployment patterns: server-side Node.js applications rendering Handlebars templates with user-supplied context data face critical exposure, while runtime-only deployments or static templates are inherently protected. The availability of a working POC in the security advisory significantly lowers the barrier for weaponization. This represents a genuine priority for organizations using Handlebars in server-side rendering with dynamic context, particularly web applications and API services that accept user input into template contexts. |
| Exploit ScenarioDerived | An attacker identifies a Node.js web application using Handlebars for server-side rendering where user profile data is merged into template context. The application uses a dynamic partial pattern like {{> (lookup user 'templateChoice')}} to allow customizable layouts. The attacker registers an account and sets the 'templateChoice' field to a crafted JavaScript object containing a malicious AST structure with injected code in the depth property. When the application renders the user's profile page, the Handlebars runtime processes the crafted object through resolvePartial() and invokePartial(), triggering compilation of the attacker-controlled AST. The generated JavaScript executes arbitrary commands with the privileges of the Node.js process, enabling data exfiltration, lateral movement, or complete server compromise. Publicly available exploit code exists in the proof-of-concept documented in the GitHub security advisory. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Mar 27, 2026
Remote code execution in Handlebars templating engine (npm package) allows unauthenticated network attackers to execute arbitrary server-side commands by exploiting dynamic partial resolution logic. Affected versions include all releases prior to v4.7.9. Attack requires the adversary to control context data passed to templates that use dynamic partial lookups. A proof-of-concept exploit demonstrates arbitrary code execution and is publicly documented. CVSS score of 8.1 reflects high complexity due to the need for specific template patterns and attacker-controlled context values.
RemediationAI
Upgrade Handlebars to version v4.7.9 or later, as documented in the release notes at https://github.com/handlebars-lang/handlebars.js/releases/tag/v4.7.9 and patched via commit 68d8df5a88e0a26fe9e6084c5c6aaebe67b07da2 available at https://github.com/handlebars-lang/handlebars.js/commit/68d8df5a88e0a26fe9e6084c5c6aaebe67b07da2. Organizations unable to immediately upgrade should implement one of three workarounds: migrate to the runtime-only Handlebars build (require('handlebars/runtime')) which eliminates the compile() function from the attack surface, implement strict input sanitization to ensure no context property contains non-primitive objects that could be passed to dynamic partials, or refactor templates to eliminate dynamic partial lookups ({{> (lookup ...)}}) when rendering user-controlled data. Review all template implementations for patterns combining lookup helpers with partial invocation syntax.
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 2 packages in npm, euvd
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
Handlebars is a widely-deployed JavaScript templating engine (pkg:npm/handlebars) used for server-side and client-side HTML generation. This vulnerability exploits CWE-94 (Improper Control of Generation of Code, 'Code Injection') through a logic flaw in the partial resolution mechanism. When resolvePartial() processes a crafted object with a 'call: true' property in lib/handlebars/runtime.js, it bypasses all conditional guards and returns the object unchanged. The subsequent invokePartial() function misinterprets this non-function object as an uncompiled template source and passes it to env.compile(). Because the crafted object is structured as a valid Handlebars Abstract Syntax Tree containing injected JavaScript code fragments, the compilation step generates and executes arbitrary attacker-controlled commands. The vulnerability chain requires dynamic partial lookups (e.g., {{> (lookup . "key")}}) combined with attacker-influenced template context data.
Know when the next one hits your stack
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Primary rating from Vendor (https://github.com/handlebars-lang/handlebars.js).
CVSS VectorVendor: https://github.com/handlebars-lang/handlebars.js
Lifecycle Timeline
2DescriptionCVE.org
Summary
A crafted object placed in the template context can bypass all conditional guards in resolvePartial() and cause invokePartial() to return undefined. The Handlebars runtime then treats the unresolved partial as a source that needs to be compiled, passing the crafted object to env.compile(). Because the object is a valid Handlebars AST containing injected code, the generated JavaScript executes arbitrary commands on the server. The attack requires the adversary to control a value that can be returned by a dynamic partial lookup.
Description
The vulnerable code path spans two functions in lib/handlebars/runtime.js:
resolvePartial(): A crafted object with call: true satisfies the first branch condition (partial.call) and causes an early return of the original object itself, because none of the remaining conditionals (string check, options.partials lookup, etc.) match a plain object. The function returns the crafted object as-is.
invokePartial(): When resolvePartial returns a non-function object, invokePartial produces undefined. The runtime interprets undefined as "partial not yet compiled" and calls env.compile(partial, ...) where partial is the crafted AST object. The JavaScript code generator processes the AST and emits JavaScript containing the injected payload, which is then evaluated.
Minimum prerequisites:
- The template uses a dynamic partial lookup:
{{> (lookup . "key")}}or equivalent. - The adversary can set the value of the looked-up context property to a crafted object.
In server-side rendering scenarios where templates process user-supplied context data, this enables full Remote Code Execution.
Proof of Concept
const Handlebars = require('handlebars');
const vulnerableTemplate = `{{> (lookup . "payload")}}`;
const maliciousContext = {
payload: {
call: true, // bypasses the primary resolvePartial branch
type: "Program",
body: [
{
type: "MustacheStatement",
depth: 0,
path: {
type: "PathExpression",
parts: ["pop"],
original: "this.pop",
// Injected code breaks out of the generated function's argument list
depth: "0])),function () {console.error('VULNERABLE: object -> dynamic partial -> RCE');}()));//",
},
},
],
},
};
Handlebars.compile(vulnerableTemplate)(maliciousContext);
// Prints: VULNERABLE: object -> dynamic partial -> RCEWorkarounds
- Use the runtime-only build (
require('handlebars/runtime')). Withoutcompile(), the fallback compilation path ininvokePartialis unreachable. - Sanitize context data before rendering: ensure no value in the context is a non-primitive object that could be passed to a dynamic partial.
- Avoid dynamic partial lookups (
{{> (lookup ...)}}) when context data is user-controlled.
Blast Radius
ecosystem impact- 3 npm packages depend on handlebars (1 direct, 2 indirect)
Ecosystem-wide dependent count for version 4.0.0.
Executive ViewAI
The Handlebars templating engine (npm package, versions prior to v4.7.9) contains a remote code execution vulnerability that allows unauthenticated attackers to execute arbitrary commands on affected servers. Organizations using Handlebars in web applications or server-side rendering are at risk if they process user-controlled data through dynamic template partials; successful exploitation could result in complete server compromise and unauthorized access to sensitive data.
Apply vendor patch (upgrade to Handlebars v4.7.9 or later). If immediate patching is not feasible, implement input validation and sanitization for all context data passed to templates, disable dynamic partial resolution features where possible, and restrict Handlebars template processing to trusted input sources only.
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Code injection occurs when an application accepts user input and passes it directly into a language interpreter or evaluator without proper sanitization.
Remote Code Execution represents the critical moment when an attacker successfully runs arbitrary code on a target system without physical access.
EUVD-2026-16860
GHSA-xhpv-hc6g-r9c6
NVD
CVE.org
EPSS
Vulnrichment
VulDB
Exploit-DB