Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessSubmit crafted AST object as JSON
-
DeliveryApplication passes AST to Handlebars.compile()
-
ExploitMalicious value bypasses selective literal validation
-
ExecutionCompiler emits attacker JavaScript into template function
-
ImpactArbitrary code execution in server process
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 | Exploitation requires the application to pass an attacker-controllable pre-parsed AST object - not a template string - into Handlebars.compile() or Handlebars.precompile() on an affected version (4.0.0 through 4.7.9). The attacker must be able to inject a JavaScript expression into one of the fields left unvalidated by the 4.7.9 hardening: Program.blockParams.length, a non-PathExpression parameter depth, a non-string StringLiteral.value, or a non-string PathExpression.original. LIMITING FACTORS: applications that compile only template strings (the standard and documented usage) are completely unaffected; the untrusted AST must originate from a source the attacker controls (request body, user-writable storage); and no authentication-level or user-interaction requirement is inherent, but the vulnerable code path is a non-default application design pattern that the vendor explicitly warns against. Fixed in 4.7.10. |
| Impact | The input CVSS 3.1 vector (AV:N/AC:L/PR:N/UI:N/C:H/I:H/A:H = 9.8 Critical) presents this as trivially remotely exploitable, but that score materially overstates real-world risk because it ignores the central precondition stated in the description: the vulnerable code path is reached ONLY when an application passes an attacker-controllable pre-parsed AST object (rather than a template string) into Handlebars.compile() or Handlebars.precompile(). The vendor explicitly notes 'Applications that pass only template strings are not affected,' and the patch commit adds documentation warning that ASTs should be treated as code and never sourced from untrusted input - meaning the default and overwhelmingly common usage pattern (compiling string templates) is NOT vulnerable. This is therefore a high-CVSS flaw whose true exploitability is gated by an atypical, insecure application design choice, which belongs under AC/AT rather than being free in the base score. On exploitation signals: no CISA KEV entry is present in the data (not actively exploited per available signals), no public exploit code is referenced, and no EPSS score was provided, so there is no evidence of in-the-wild activity. No SSVC decision data was supplied. The conflict to flag explicitly: CVSS claims AC:L/PR:N (easy, unauthenticated), yet the description's 'attacker who can supply an object instead of a template string' describes a non-default, application-architecture-dependent condition that most deployments will never meet - verify against your own code whether any untrusted AST ever reaches compile/precompile before treating this as Critical. |
| Exploit ScenarioDerived | An application deserializes a Handlebars template AST from an untrusted source (e.g. a JSON request body or user-writable storage) and passes that object directly into Handlebars.compile() or Handlebars.precompile(). The attacker submits a crafted AST embedding a JavaScript expression in an unvalidated field such as PathExpression.original, a non-string StringLiteral.value, Program.blockParams.length, or a non-PathExpression parameter depth; when the compiled template renders (or the precompiled output is loaded), the injected expression executes as code in the server process. No public exploit code or active exploitation is identified in the provided data. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Oct 06, 2026
Code execution in Handlebars.js versions 4.0.0 through 4.7.9 occurs when an application hands an attacker-controllable, pre-parsed AST object - rather than a template string - to Handlebars.compile() or Handlebars.precompile(); the compiler writes JavaScript expressions carried in unchecked AST fields straight into the generated code, which then executes in the server process wherever the compiled output runs. The flaw is an incomplete fix: the AST validation added in 4.7.9 for CVE-2026-33937 covered only PathExpression, NumberLiteral and BooleanLiteral values, leaving fields such as Program.blockParams.length, a non-PathExpression parameter depth, a non-string StringLiteral.value and a non-string PathExpression.original unvalidated. The published CVSS 3.1 vector is AV:N/AC:L/PR:N/UI:N/C:H/I:H/A:H (9.8) and treats this as trivially remote and unauthenticated, but that materially overstates real-world exposure: the vulnerable path is a non-default application design pattern that the vendor explicitly warns against, so applications that compile only template strings - the standard, documented usage - are completely unaffected, and no public exploit code has been identified at time of analysis. Vendor-released patch: 4.7.10.
RemediationAI
Upgrade the handlebars npm package to 4.7.10 or later - the vendor-released patch, published at https://github.com/handlebars-lang/handlebars.js/releases/tag/v4.7.10 and detailed in advisory GHSA-8r5x-fm3f-whwj, the fixing commit 703fdcc5fd6cc8d1cc0c33cc19de40c467c4b8d2 and PR 2185 - and, because 4.7.10 is the only release that closes the remaining unvalidated fields (Program.blockParams.length, non-PathExpression parameter depth, non-string StringLiteral.value and non-string PathExpression.original), treat 4.7.9 as still vulnerable. If an immediate upgrade is not possible, the effective compensating control is architectural rather than configuration-based: ensure no code path passes an AST object into compile() or precompile() that originates from a request body, user-writable storage, or any other attacker-influenced source - parse only trusted template source strings at the point of compilation and cache or transfer the template source text (re-parsing it where it is compiled) instead of serializing ASTs; note the trade-off that this reintroduces parse cost on each render if a caching layer previously stored ASTs. The vendor explicitly documents that the compiler's internal hardening is defense in depth and not a guarantee, so input-origin control is the reliable mitigation. For auditing, grep the codebase for compile( and precompile( call sites and verify each argument is a string literal or server-generated template, and treat any JSON-decoded object reaching those functions as a finding. No network-level or authentication-based workaround applies, since the flaw is triggered inside the application's own process rather than over an exposed protocol.
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 JavaScript semantic-templating library whose compile() and precompile() functions translate either template source text or a pre-parsed AST (the Handlebars AST format used by tooling) into JavaScript functions. The root cause is CWE-94, Improper Control of Generation of Code ('Code Injection'), arising from type confusion at the compiler boundary: lib/handlebars/compiler/javascript-compiler.js trusts every opcode argument to be a safe primitive, so any value the AST compiler passes through is emitted verbatim into generated source. The 4.7.9 fix for CVE-2026-33937 added validateInputAst() in lib/handlebars/compiler/base.js, which only checked PathExpression.depth/parts, NumberLiteral.value and BooleanLiteral.value. The 4.7.10 patch removes that broad pre-walk entirely and instead moves validation to the exact points of use inside compiler.js - validateDepth(), validateParts(), validateLiteral(), validateBlockParams(), plus type checks on StringLiteral.value, hash pair keys and hash pairs arrays - reflecting the vendor's design position that compile and precompile 'turn an AST into JavaScript, so treat it like code'. Fields left unchecked at 4.7.9 include Program.blockParams.length, a non-PathExpression parameter depth, a non-string StringLiteral.value and a non-string PathExpression.original; injecting a JavaScript expression into any of these causes it to be concatenated into the emitted program, yielding arbitrary code execution in the Node.js process hosting the compiler output. There is no CPE data supplied in this feed, but the affected component is unambiguously the npm package handlebars (handlebars-lang/handlebars.js) at versions 4.0.0 through 4.7.9.
Know when JavaScript gets its next vulnerability
- 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:L/PR:N/UI:N/S:U/C:H/I:H/A:H
AV:N and PR:N since untrusted AST can arrive over the network unauthenticated, but AC:H because exploitation depends on the non-default condition that an application feeds untrusted AST objects to compile/precompile; full RCE justifies C/I/A:H.
Primary rating from Vendor (github).
CVSS VectorVendor: github
Lifecycle Timeline
2DescriptionCVE.org
Handlebars provides the power necessary to let users build semantic templates. From 4.0.0 until 4.7.10, Handlebars.compile() and Handlebars.precompile() accept pre-parsed AST objects while validating only selected PathExpression, NumberLiteral, and BooleanLiteral values. This issue bypasses the AST validation introduced in version 4.7.9 for CVE-2026-33937. An attacker who can supply an object instead of a template string can place JavaScript expressions in unchecked values such as Program.blockParams.length, a non-PathExpression parameter depth, a non-string StringLiteral.value, or a non-string PathExpression.original. The compiler emits those values into generated JavaScript, causing code execution in the server process when compile output renders or wherever precompile output is loaded. Applications that pass only template strings are not affected. This issue is fixed in version 4.7.10.
Blast Radius
ecosystem impact- 3 npm packages depend on handlebars (1 direct, 2 indirect)
Ecosystem-wide dependent count for version 4.0.0.
Technical POC Analysis
Bug class: CWE-94, Improper Control of Generation of Code, with CWE-843 Type Confusion.
Full technical POC analysis - root cause, step-by-step exploitation and patch breakdown - is part of the Pro and Business plans.
Executive ViewAI
Handlebars.js versions 4.0.0 through 4.7.9 contain a code-execution flaw that lets an attacker run arbitrary JavaScript inside the server process of any application that feeds untrusted, pre-parsed template structures into Handlebars.compile() or Handlebars.precompile(). The published 9.8 score rates this as remote and unauthenticated, but the vulnerable path is a non-default application design pattern rather than the library's normal string-based usage, so real-world exposure depends on whether individual services pass attacker-influenceable objects to the compiler. No public exploit has been identified at time of analysis and no vendor patch is available, making this a code-hygiene and inventory problem rather than an imminent mass-exploitation event.
No vendor-released patch identified at time of analysis. Interim mitigations: never pass attacker-controllable or untrusted AST objects to Handlebars.compile()/Handlebars.precompile() - compile only trusted, string-typed templates; validate, whitelist or deep-freeze AST fields (blockParams lengths, parameter depth, StringLiteral.value, PathExpression.original) before compilation; constrain where compiled output executes (sandboxed worker, least-privilege process, no shell access, restricted egress); and monitor Node.js services for anomalous process execution or network connections.
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.
More in JavaScript
View allCommand injection in simple-git, the Node.js library for running git commands and published on npm, affects all releases
Stored DOM-based cross-site scripting in Paella Player's closed-caption rendering path (paella-core before 2.12.11) allo
Authorization bypass in Wiki.js through 2.5.314 allows an authenticated user who has been granted access to at least one
Untrusted git configuration includes reachable through simple-git before 4.0.0 let an attacker execute arbitrary command
Improper memory allocation control in ExifReader before 4.41.1 allows remote attackers to exhaust heap memory and termin
Deeply nested brace patterns cause unbounded recursion in the npm brace-expansion library, exhausting the native stack a
Stack exhaustion in the npm library brace-expansion (all versions prior to 1.1.19, 2.1.5, 3.0.7, and 5.0.10) lets a craf
Server-side request forgery in Wiki.js through 2.5.314 lets an authenticated user who holds page-editing permissions for
The JavaScript library ip-address (npm) fails to treat the NAT64 local-use prefix 64:ff9b:1::/48 as private, so applicat
Authorization bypass in the @grpc/grpc-js-xds package (the xDS/RBAC extension for @grpc/grpc-js) lets a request for one
Cross-family subnet comparisons in the ip-address npm library (all versions before 10.7.1) can cause isInSubnet and isHo
Denial of service in the ip-address JavaScript/npm library (all versions prior to 10.7.1) lets remote attackers stall or
EUVD-2026-93969
GHSA-8r5x-fm3f-whwj
NVD
CVE.org
EPSS
Vulnrichment
Exploit-DB