handlebars
Ecosystem: npm
Downloads: 187.75 Mln
- 6CriticalAffects 7 versions
- 10HighAffects 16 versions
- 0MediumAffects 0 versions
- 7ModerateAffects 7 versions
- 1LowAffects 1 version
- Critical6 (25.0%)
- High10 (41.7%)
- Medium0 (0.0%)
- Moderate7 (29.2%)
- Low1 (4.2%)
Monthly breakdown
- Critical
- High
- Medium
- Moderate
- Low
- 3 vulnerabilities
- Critical: 2
- High: 0
- Medium: 0
- Moderate: 1
- Low: 0
- 8 vulnerabilities
- Critical: 1
- High: 4
- Medium: 0
- Moderate: 2
- Low: 1
- 3 vulnerabilities
- Critical: 1
- High: 2
- Medium: 0
- Moderate: 0
- Low: 0
- 1 vulnerabilities
- Critical: 1
- High: 0
- Medium: 0
- Moderate: 0
- Low: 0
- 4 vulnerabilities
- Critical: 0
- High: 3
- Medium: 0
- Moderate: 1
- Low: 0
- 1 vulnerabilities
- Critical: 1
- High: 0
- Medium: 0
- Moderate: 0
- Low: 0
- 1 vulnerabilities
- Critical: 0
- High: 0
- Medium: 0
- Moderate: 1
- Low: 0
- 1 vulnerabilities
- Critical: 0
- High: 1
- Medium: 0
- Moderate: 0
- Low: 0
- 1 vulnerabilities
- Critical: 0
- High: 0
- Medium: 0
- Moderate: 1
- Low: 0
- 1 vulnerabilities
- Critical: 0
- High: 0
- Medium: 0
- Moderate: 1
- Low: 0
Vulnerabilities (24)
Known vulnerabilities affecting handlebars, based on data from OSV.
| ID | Severity | Summary | Affected versions | Published | Source |
|---|---|---|---|---|---|
| GHSA-8r5x-fm3f-whwj | Critical | Handlebars: JavaScript Injection via AST Type Confusion in compile (bypass of CVE-2026-33937)## Summary `Handlebars.compile()` and `Handlebars.precompile()` accept a pre-parsed AST as well as a template string. Handlebars 4.7.9 added validation for such ASTs. It only checks values on `PathExpression`, `NumberLiteral` and `BooleanLiteral` nodes, and the compiler still writes several other AST values into the generated JavaScript unchecked. If an application passes an untrusted object to `compile()` or `precompile()`, such as a parsed JSON request body, that object can carry arbitrary JavaScript. With `compile()`, the code runs on the server when the template renders. With `precompile |
| GitHub (opens in a new tab) | |
| GHSA-p8wg-vrv2-v86f | Critical | Handlebars: JavaScript Injection via Own Property Check Bypass## Summary Handlebars can expose the `Function` constructor despite its prototype-access deny list. When a template reaches `Function.prototype`, its own `constructor` property is returned before the deny list is checked. An attacker who can render a controlled template with `allowProtoMethodsByDefault: true` can inject and execute arbitrary JavaScript, leading to Remote Code Execution on the server. ## Description `lookupProperty` trusts own properties: ```js if (Object.prototype.hasOwnProperty.call(parent, propertyName)) { return result; } ``` Normally, prototype-derived values reach |
| GitHub (opens in a new tab) | |
| GHSA-xw65-4hp5-5hc7 | Moderate | Handlebars: JavaScript Injection via Unsafe Inline Embedding of Precompiled Templates## Summary `Handlebars.precompile()` generates JavaScript source that is commonly embedded in browser `<script>` elements. Before the fix, static template text containing `</script>` was emitted unchanged. HTML parsers recognize `</script>` even inside a JavaScript string literal, closing the surrounding script element and allowing following attacker-controlled markup to be parsed and executed. This affects applications that precompile attacker-controlled templates and embed the generated source directly in an HTML `<script>` element. It does not affect ordinary server-side rendering or prec |
| GitHub (opens in a new tab) | |
| GHSA-442j-39wm-28r2 | Low | Handlebars.js has a Property Access Validation Bypass in container.lookup## Summary In `lib/handlebars/runtime.js`, the `container.lookup()` function uses `container.lookupProperty()` as a gate check to enforce prototype-access controls, but then discards the validated result and performs a second, unguarded property access (`depths[i][name]`). This Time-of-Check Time-of-Use (TOCTOU) pattern means the security check and the actual read are decoupled, and the raw access bypasses any sanitization that `lookupProperty` may perform. Only relevant when the **compat** compile option is enabled (`{compat: true}`), which activates `depthedLookup` in `lib/handlebars/compi |
| GitHub (opens in a new tab) | |
| GHSA-7rx3-28cr-v5wh | Moderate | Handlebars.js has a Prototype Method Access Control Gap via Missing __lookupSetter__ Blocklist Entry## Summary The prototype method blocklist in `lib/handlebars/internal/proto-access.js` blocks `constructor`, `__defineGetter__`, `__defineSetter__`, and `__lookupGetter__`, but omits the symmetric `__lookupSetter__`. This omission is only exploitable when the non-default runtime option `allowProtoMethodsByDefault: true` is explicitly set — in that configuration `__lookupSetter__` becomes accessible while its counterparts remain blocked, creating an inconsistent security boundary. `4.6.0` is the version that introduced `protoAccessControl` and the `allowProtoMethodsByDefault` runtime option. |
| GitHub (opens in a new tab) | |
| GHSA-2w6w-674q-4c4q | Critical | Handlebars.js has JavaScript Injection via AST Type Confusion## Summary `Handlebars.compile()` accepts a pre-parsed AST object in addition to a template string. The `value` field of a `NumberLiteral` AST node is emitted directly into the generated JavaScript without quoting or sanitization. An attacker who can supply a crafted AST to `compile()` can therefore inject and execute arbitrary JavaScript, leading to Remote Code Execution on the server. ## Description `Handlebars.compile()` accepts either a template string or a pre-parsed AST. When an AST is supplied, the JavaScript code generator in `lib/handlebars/compiler/javascript-compiler.js` emits `N |
| GitHub (opens in a new tab) | |
| GHSA-3mfm-83xf-c92r | High | Handlebars.js has JavaScript Injection via AST Type Confusion by tampering @partial-block## Summary The `@partial-block` special variable is stored in the template data context and is reachable and mutable from within a template via helpers that accept arbitrary objects. When a helper overwrites `@partial-block` with a crafted Handlebars AST, a subsequent invocation of `{{> @partial-block}}` compiles and executes that AST, enabling arbitrary JavaScript execution on the server. ## Description Handlebars stores `@partial-block` in the `data` frame that is accessible to templates. In nested contexts, a parent frame's `@partial-block` is reachable as `@_parent.partial-block`. Becau |
| GitHub (opens in a new tab) | |
| GHSA-9cx6-37pm-9jff | High | Handlebars.js has Denial of Service via Malformed Decorator Syntax in Template Compilation## Summary When a Handlebars template contains decorator syntax referencing an unregistered decorator (e.g. `{{*n}}`), the compiled template calls `lookupProperty(decorators, "n")`, which returns `undefined`. The runtime then immediately invokes the result as a function, causing an unhandled `TypeError: ... is not a function` that crashes the Node.js process. Any application that compiles user-supplied templates without wrapping the call in a `try/catch` is vulnerable to a single-request Denial of Service. ## Description In `lib/handlebars/compiler/javascript-compiler.js`, the code generate |
| GitHub (opens in a new tab) | |
| GHSA-xhpv-hc6g-r9c6 | High | Handlebars.js has JavaScript Injection via AST Type Confusion when passing an object as dynamic partial## 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 |
| GitHub (opens in a new tab) | |
| GHSA-xjpj-3mr7-gcpf | High | Handlebars.js has JavaScript Injection in CLI Precompiler via Unescaped Names and Options## Summary The Handlebars CLI precompiler (`bin/handlebars` / `lib/precompiler.js`) concatenates user-controlled strings — template file names and several CLI options — directly into the JavaScript it emits, without any escaping or sanitization. An attacker who can influence template filenames or CLI arguments can inject arbitrary JavaScript that executes when the generated bundle is loaded in Node.js or a browser. ## Description `lib/precompiler.js` generates JavaScript source by string-interpolating several values directly into the output. Four distinct injection points exist: ### 1. Tem |
| GitHub (opens in a new tab) |
- GHSA-8r5x-fm3f-whwjCriticalHandlebars: JavaScript Injection via AST Type Confusion in compile (bypass of CVE-2026-33937)
>= 4.0.0, < 4.7.10
## Summary `Handlebars.compile()` and `Handlebars.precompile()` accept a pre-parsed AST as well as a template string. Handlebars 4.7.9 added validation for such ASTs. It only checks values on `PathExpression`, `NumberLiteral` and `BooleanLiteral` nodes, and the compiler still writes several other AST values into the generated JavaScript unchecked. If an application passes an untrusted object to `compile()` or `precompile()`, such as a parsed JSON request body, that object can carry arbitrary JavaScript. With `compile()`, the code runs on the server when the template renders. With `precompile
CVE: CVE-2026-106446
- GHSA-p8wg-vrv2-v86fCriticalHandlebars: JavaScript Injection via Own Property Check Bypass
>= 3.0.0, < 4.7.10
## Summary Handlebars can expose the `Function` constructor despite its prototype-access deny list. When a template reaches `Function.prototype`, its own `constructor` property is returned before the deny list is checked. An attacker who can render a controlled template with `allowProtoMethodsByDefault: true` can inject and execute arbitrary JavaScript, leading to Remote Code Execution on the server. ## Description `lookupProperty` trusts own properties: ```js if (Object.prototype.hasOwnProperty.call(parent, propertyName)) { return result; } ``` Normally, prototype-derived values reach
CVE: CVE-2026-106445
- GHSA-xw65-4hp5-5hc7ModerateHandlebars: JavaScript Injection via Unsafe Inline Embedding of Precompiled Templates
>= 4.0.0, < 4.7.10
## Summary `Handlebars.precompile()` generates JavaScript source that is commonly embedded in browser `<script>` elements. Before the fix, static template text containing `</script>` was emitted unchanged. HTML parsers recognize `</script>` even inside a JavaScript string literal, closing the surrounding script element and allowing following attacker-controlled markup to be parsed and executed. This affects applications that precompile attacker-controlled templates and embed the generated source directly in an HTML `<script>` element. It does not affect ordinary server-side rendering or prec
CVE: CVE-2026-106444
- GHSA-442j-39wm-28r2LowHandlebars.js has a Property Access Validation Bypass in container.lookup
>= 4.0.0, < 4.7.9
## Summary In `lib/handlebars/runtime.js`, the `container.lookup()` function uses `container.lookupProperty()` as a gate check to enforce prototype-access controls, but then discards the validated result and performs a second, unguarded property access (`depths[i][name]`). This Time-of-Check Time-of-Use (TOCTOU) pattern means the security check and the actual read are decoupled, and the raw access bypasses any sanitization that `lookupProperty` may perform. Only relevant when the **compat** compile option is enabled (`{compat: true}`), which activates `depthedLookup` in `lib/handlebars/compi
- GHSA-7rx3-28cr-v5whModerateHandlebars.js has a Prototype Method Access Control Gap via Missing __lookupSetter__ Blocklist Entry
>= 4.6.0, < 4.7.9
## Summary The prototype method blocklist in `lib/handlebars/internal/proto-access.js` blocks `constructor`, `__defineGetter__`, `__defineSetter__`, and `__lookupGetter__`, but omits the symmetric `__lookupSetter__`. This omission is only exploitable when the non-default runtime option `allowProtoMethodsByDefault: true` is explicitly set — in that configuration `__lookupSetter__` becomes accessible while its counterparts remain blocked, creating an inconsistent security boundary. `4.6.0` is the version that introduced `protoAccessControl` and the `allowProtoMethodsByDefault` runtime option.
- GHSA-2w6w-674q-4c4qCriticalHandlebars.js has JavaScript Injection via AST Type Confusion
>= 4.0.0, < 4.7.9
## Summary `Handlebars.compile()` accepts a pre-parsed AST object in addition to a template string. The `value` field of a `NumberLiteral` AST node is emitted directly into the generated JavaScript without quoting or sanitization. An attacker who can supply a crafted AST to `compile()` can therefore inject and execute arbitrary JavaScript, leading to Remote Code Execution on the server. ## Description `Handlebars.compile()` accepts either a template string or a pre-parsed AST. When an AST is supplied, the JavaScript code generator in `lib/handlebars/compiler/javascript-compiler.js` emits `N
CVE: CVE-2026-33937
- GHSA-3mfm-83xf-c92rHighHandlebars.js has JavaScript Injection via AST Type Confusion by tampering @partial-block
>= 4.0.0, < 4.7.9
## Summary The `@partial-block` special variable is stored in the template data context and is reachable and mutable from within a template via helpers that accept arbitrary objects. When a helper overwrites `@partial-block` with a crafted Handlebars AST, a subsequent invocation of `{{> @partial-block}}` compiles and executes that AST, enabling arbitrary JavaScript execution on the server. ## Description Handlebars stores `@partial-block` in the `data` frame that is accessible to templates. In nested contexts, a parent frame's `@partial-block` is reachable as `@_parent.partial-block`. Becau
CVE: CVE-2026-33938
- GHSA-9cx6-37pm-9jffHighHandlebars.js has Denial of Service via Malformed Decorator Syntax in Template Compilation
>= 4.0.0, < 4.7.9
## Summary When a Handlebars template contains decorator syntax referencing an unregistered decorator (e.g. `{{*n}}`), the compiled template calls `lookupProperty(decorators, "n")`, which returns `undefined`. The runtime then immediately invokes the result as a function, causing an unhandled `TypeError: ... is not a function` that crashes the Node.js process. Any application that compiles user-supplied templates without wrapping the call in a `try/catch` is vulnerable to a single-request Denial of Service. ## Description In `lib/handlebars/compiler/javascript-compiler.js`, the code generate
CVE: CVE-2026-33939
- GHSA-xhpv-hc6g-r9c6HighHandlebars.js has JavaScript Injection via AST Type Confusion when passing an object as dynamic partial
>= 4.0.0, < 4.7.9
## 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
CVE: CVE-2026-33940
- GHSA-xjpj-3mr7-gcpfHighHandlebars.js has JavaScript Injection in CLI Precompiler via Unescaped Names and Options
>= 4.0.0, < 4.7.9
## Summary The Handlebars CLI precompiler (`bin/handlebars` / `lib/precompiler.js`) concatenates user-controlled strings — template file names and several CLI options — directly into the JavaScript it emits, without any escaping or sanitization. An attacker who can influence template filenames or CLI arguments can inject arbitrary JavaScript that executes when the generated bundle is loaded in Node.js or a browser. ## Description `lib/precompiler.js` generates JavaScript source by string-interpolating several values directly into the output. Four distinct injection points exist: ### 1. Tem
CVE: CVE-2026-33941