Skip to main content

Handlebars.js EUVDEUVD-2026-93969

| CVE-2026-106446 CRITICAL
Code Injection (CWE-94)
2026-10-06 security-advisories@github.com GHSA-8r5x-fm3f-whwj
9.8
CVSS 3.1 · Vendor: github
View

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain

  1. Access
    Submit crafted AST object as JSON
  2. Delivery
    Application passes AST to Handlebars.compile()
  3. Exploit
    Malicious value bypasses selective literal validation
  4. Execution
    Compiler emits attacker JavaScript into template function
  5. Impact
    Arbitrary 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.

Act Now Prioritize within 24-48h. Why: CRITICAL severity.
Patch available 0.6% exploitation probability (EPSS)

Get an e-mail when this CVE is exploited, patched or re-scored. Free account.

Alert me

AnalysisAIv1 – 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

handlebars.js 4.0.0, < 4.7.10

Affected Packages

npm handlebars fix: 4.7.10
euvd handlebars_js_4_0_0 fix: 4.7.10

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

Vendor (github) PRIMARY 9.8 CRITICAL
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
vuln.today AI 8.1 HIGH

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.

3.1 AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
4.0 AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
Red Hat 8.1 HIGH

Primary rating from Vendor (github).

CVSS VectorVendor: github

Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality
High
Integrity
High
Availability
High

Lifecycle Timeline

2
Patch available
Oct 06, 2026 - 21:05 EUVD
CVE Published
Oct 06, 2026 - 20:17 cve.org
CRITICAL 9.8

DescriptionCVE.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
† from your stack dependencies † transitive graph · vuln.today resolves 4-path depth
  • 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

Why It Matters

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.

Business Impact: High
Compensating Controls

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

EPSS Score
0.6%
Top 51% exploitable
Prevalence
High
Handlebars.js is a top-tier, heavily-downloaded JavaScript templating library
Threat Intel
1
1 source
Data Quality
5 sources
Confidence: Medium
EUVD NVD CVE.org EPSS Vulnrichment GHSA Vendor GitHub

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.

SignalValue
Severity CRITICAL
CISA KEV No
Public POC No
EPSS 0.6%
Patch available Yes
Active threat No
Deciding rule
CRITICAL severity
What every action level means
Emergency Immediate action required. Criteria: CRITICAL + in CISA KEV (actively exploited) without patch, OR CRITICAL + EPSS > 30% without patch, OR CRITICAL + active threat signals without patch.
Act Now Prioritize within 24-48h. Criteria: in KEV with patch available, OR CRITICAL + public POC, OR HIGH + EPSS > 10%, OR CRITICAL + active threat, OR any CRITICAL severity.
This Week Schedule remediation this week. Criteria: HIGH severity (CVSS 7.0-8.9). Patch within normal change window.
This Month Plan within 30 days. Criteria: MEDIUM severity (CVSS 4.0-6.9), lower exploitation probability. Include in regular patch cycle.
Monitor Track and reassess. Criteria: LOW severity (CVSS 0.1-3.9), minimal exploitation risk. No immediate action needed.

SSVC AssessmentENISA

SSVC Decision
Scheduled
Exploitation
Poc
System Exposure· derived
Open
Automatable
Yes
Human Impact
High
Technical Impact
Total

Priority Score

50
Low Medium High Critical
KEV: 0
EPSS: +1
CVSS: +49
PoC: 0
Weaponized: 0
Threat intel: 0
Gov advisory: 0

Attack Technique

Code Injection CRITICAL

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.

CVE-2026-102827 CRITICAL POC
9.8 Sep 29

Command injection in simple-git, the Node.js library for running git commands and published on npm, affects all releases

CVE-2026-77615 HIGH POC
8.7 Sep 17

Stored DOM-based cross-site scripting in Paella Player's closed-caption rendering path (paella-core before 2.12.11) allo

CVE-2026-92776 HIGH POC
8.6 Sep 16

Authorization bypass in Wiki.js through 2.5.314 allows an authenticated user who has been granted access to at least one

CVE-2026-102826 HIGH POC
8.1 Sep 29

Untrusted git configuration includes reachable through simple-git before 4.0.0 let an attacker execute arbitrary command

CVE-2026-85715 HIGH POC
7.5 Sep 17

Improper memory allocation control in ExifReader before 4.41.1 allows remote attackers to exhaust heap memory and termin

CVE-2026-102278 HIGH POC
7.5 Sep 28

Deeply nested brace patterns cause unbounded recursion in the npm brace-expansion library, exhausting the native stack a

CVE-2026-102276 HIGH POC
7.5 Sep 28

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

CVE-2026-92775 HIGH POC
7.1 Sep 16

Server-side request forgery in Wiki.js through 2.5.314 lets an authenticated user who holds page-editing permissions for

CVE-2026-101910 MEDIUM POC
6.9 Sep 28

The JavaScript library ip-address (npm) fails to treat the NAT64 local-use prefix 64:ff9b:1::/48 as private, so applicat

CVE-2026-101914 MEDIUM POC
6.5 Sep 28

Authorization bypass in the @grpc/grpc-js-xds package (the xDS/RBAC extension for @grpc/grpc-js) lets a request for one

CVE-2026-101912 MEDIUM POC
6.3 Sep 28

Cross-family subnet comparisons in the ip-address npm library (all versions before 10.7.1) can cause isInSubnet and isHo

CVE-2026-101911 MEDIUM POC
6.3 Sep 28

Denial of service in the ip-address JavaScript/npm library (all versions prior to 10.7.1) lets remote attackers stall or

Vendor StatusVendor

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy