CVE-2026-33940
Handlebars.js has JavaScript Injection via AST Type Confusion when passing an object as dynamic partial
Handlebars provides the power necessary to let users build semantic templates. In versions 4.0.0 through 4.7.8, 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. Version 4.7.9 fixes the issue. Some workarounds are available. First, use the runtime-only build (require('handlebars/runtime')). Without compile(), the fallback compilation path in invokePartial is unreachable. Second, sanitize context data before rendering: Ensure no value in the context is a non-primitive object that could be passed to a dynamic partial. Third, avoid dynamic partial lookups ({{> (lookup ...)}}) when context data is user-controlled.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- High
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- High
- Integrity
- High
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
8.1
Handlebars.js has JavaScript Injection via AST Type Confusion when passing an object as dynamic partial
Handlebars provides the power necessary to let users build semantic templates. In versions 4.0.0 through 4.7.8, 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. Version 4.7.9 fixes the issue. Some workarounds are available. First, use the runtime-only build (require('handlebars/runtime')). Without compile(), the fallback compilation path in invokePartial is unreachable. Second, sanitize context data before rendering: Ensure no value in the context is a non-primitive object that could be passed to a dynamic partial. Third, avoid dynamic partial lookups ({{> (lookup ...)}}) when context data is user-controlled.
- Record
CVE-2026-33940- CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-94, CWE-843, CWE-94
- Updated
- 2026-11-02
EUVDEUVD-2026-16860
8.1
Handlebars provides the power necessary to let users build semantic templates. In versions 4.0.0 through 4.7.8, 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. Version 4.7.9 fixes the issue. Some workarounds are available. First, use the runtime-only build (require('handlebars/runtime')). Without compile(), the fallback compilation path in invokePartial is unreachable. Second, sanitize context data before rendering: Ensure no value in the context is a non-primitive object that could be passed to a dynamic partial. Third, avoid dynamic partial lookups ({{> (lookup ...)}}) when context data is user-controlled.
- Record
EUVD-2026-16860- CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-442j-39wm-28r2
3.7
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/compiler/javascript-compiler.js.
Description
The vulnerable code in lib/handlebars/runtime.js (lines 137–144):
lookup: function (depths, name) {
const len = depths.length;
for (let i = 0; i < len; i++) {
let result = depths[i] && container.lookupProperty(depths[i], name);
if (result != null) {
return depths[i][name]; // BUG: should be `return result;`
}
}
},
container.lookupProperty() (lines 119–136) enforces hasOwnProperty checks and resultIsAllowed() prototype-access controls. However, container.lookup() only uses lookupProperty as a boolean gate — if the gate passes (result != null), it then performs an independent, raw depths[i][name] access that circumvents any transformation or wrapped value that lookupProperty may have returned.
Workarounds
- Avoid enabling
{ compat: true }when rendering templates that include untrusted data. - Ensure context data objects are plain JSON (no Proxies, no getter-based accessor properties).
- Record
GHSA-442j-39wm-28r2- CVSS 3.1
- 3.7 Low
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N - Weakness
- CWE-367
- Updated
- 2026-11-02
GitHub AdvisoriesGHSA-7rx3-28cr-v5wh
4.8
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.
Description
In lib/handlebars/internal/proto-access.js:
const methodWhiteList = Object.create(null);
methodWhiteList['constructor'] = false;
methodWhiteList['__defineGetter__'] = false;
methodWhiteList['__defineSetter__'] = false;
methodWhiteList['__lookupGetter__'] = false;
// __lookupSetter__ intentionally blocked in CVE-2021-23383,
// but omitted here — creating an asymmetric blocklist
All four legacy accessor helpers (__defineGetter__, __defineSetter__, __lookupGetter__, __lookupSetter__) were involved in the exploit chain addressed by CVE-2021-23383. Three of the four were explicitly blocked; __lookupSetter__ was left out.
When allowProtoMethodsByDefault: true is set, any prototype method not present in methodWhiteList is permitted by default. Because __lookupSetter__ is absent from the list, it passes the checkWhiteList check and is accessible in templates, while __lookupGetter__ (its sibling) is correctly denied.
Workarounds
- Do not set
allowProtoMethodsByDefault: true. The default configuration is not affected. - If
allowProtoMethodsByDefaultmust be enabled, ensure templates do not reference__lookupSetter__through untrusted input.
- Record
GHSA-7rx3-28cr-v5wh- CVSS 3.1
- 4.8 Medium
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N - Weakness
- CWE-1321
- Updated
- 2026-11-02
GitHub AdvisoriesGHSA-xhpv-hc6g-r9c6
8.1
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 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 -> RCE
Workarounds
- 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.
- Record
GHSA-xhpv-hc6g-r9c6- CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-94, CWE-843
- Updated
- 2026-11-02
NVD
8.1
Handlebars provides the power necessary to let users build semantic templates. In versions 4.0.0 through 4.7.8, 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. Version 4.7.9 fixes the issue. Some workarounds are available. First, use the runtime-only build (require('handlebars/runtime')). Without compile(), the fallback compilation path in invokePartial is unreachable. Second, sanitize context data before rendering: Ensure no value in the context is a non-primitive object that could be passed to a dynamic partial. Third, avoid dynamic partial lookups ({{> (lookup ...)}}) when context data is user-controlled.
- Record
CVE-2026-33940- CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-94, CWE-843
- Updated
- 2026-11-02
Show 14 moreShow less
OSV
8.1
Handlebars.js has JavaScript Injection via AST Type Confusion when passing an object as dynamic partial
Handlebars provides the power necessary to let users build semantic templates. In versions 4.0.0 through 4.7.8, 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. Version 4.7.9 fixes the issue. Some workarounds are available. First, use the runtime-only build (require('handlebars/runtime')). Without compile(), the fallback compilation path in invokePartial is unreachable. Second, sanitize context data before rendering: Ensure no value in the context is a non-primitive object that could be passed to a dynamic partial. Third, avoid dynamic partial lookups ({{> (lookup ...)}}) when context data is user-controlled.
- Record
CVE-2026-33940- CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-843, CWE-94
- Updated
- 2026-11-02
OSVDEBIAN-CVE-2026-33940
8.1
Handlebars provides the power necessary to let users build semantic templates. In versions 4.0.0 through 4.7.8, 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. Version 4.7.9 fixes the issue. Some workarounds are available. First, use the runtime-only build (require('handlebars/runtime')). Without compile(), the fallback compilation path in invokePartial is unreachable. Second, sanitize context data before rendering: Ensure no value in the context is a non-primitive object that could be passed to a dynamic partial. Third, avoid dynamic partial lookups ({{> (lookup ...)}}) when context data is user-controlled.
- Record
DEBIAN-CVE-2026-33940- CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H - Updated
- 2026-11-02
OSVGHSA-442j-39wm-28r2
3.7
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/compiler/javascript-compiler.js.
Description
The vulnerable code in lib/handlebars/runtime.js (lines 137–144):
lookup: function (depths, name) {
const len = depths.length;
for (let i = 0; i < len; i++) {
let result = depths[i] && container.lookupProperty(depths[i], name);
if (result != null) {
return depths[i][name]; // BUG: should be `return result;`
}
}
},
container.lookupProperty() (lines 119–136) enforces hasOwnProperty checks and resultIsAllowed() prototype-access controls. However, container.lookup() only uses lookupProperty as a boolean gate — if the gate passes (result != null), it then performs an independent, raw depths[i][name] access that circumvents any transformation or wrapped value that lookupProperty may have returned.
Workarounds
- Avoid enabling
{ compat: true }when rendering templates that include untrusted data. - Ensure context data objects are plain JSON (no Proxies, no getter-based accessor properties).
- Record
GHSA-442j-39wm-28r2- CVSS 3.1
- 3.7 Low
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N - Weakness
- CWE-367
- Updated
- 2026-11-02
OSVGHSA-7rx3-28cr-v5wh
4.8
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.
Description
In lib/handlebars/internal/proto-access.js:
const methodWhiteList = Object.create(null);
methodWhiteList['constructor'] = false;
methodWhiteList['__defineGetter__'] = false;
methodWhiteList['__defineSetter__'] = false;
methodWhiteList['__lookupGetter__'] = false;
// __lookupSetter__ intentionally blocked in CVE-2021-23383,
// but omitted here — creating an asymmetric blocklist
All four legacy accessor helpers (__defineGetter__, __defineSetter__, __lookupGetter__, __lookupSetter__) were involved in the exploit chain addressed by CVE-2021-23383. Three of the four were explicitly blocked; __lookupSetter__ was left out.
When allowProtoMethodsByDefault: true is set, any prototype method not present in methodWhiteList is permitted by default. Because __lookupSetter__ is absent from the list, it passes the checkWhiteList check and is accessible in templates, while __lookupGetter__ (its sibling) is correctly denied.
Workarounds
- Do not set
allowProtoMethodsByDefault: true. The default configuration is not affected. - If
allowProtoMethodsByDefaultmust be enabled, ensure templates do not reference__lookupSetter__through untrusted input.
- Record
GHSA-7rx3-28cr-v5wh- CVSS 3.1
- 4.8 Medium
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N - Weakness
- CWE-1321
- Updated
- 2026-11-02
OSVGHSA-xhpv-hc6g-r9c6
8.1
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 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 -> RCE
Workarounds
- 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.
- Record
GHSA-xhpv-hc6g-r9c6- CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-843, CWE-94
- Updated
- 2026-11-02
OSVROOT-APP-NPM-CVE-2026-33940
8.1
CVE-2026-33940 in handlebars - Patched by Root
Root has patched CVE-2026-33940 in the handlebars package for Root:npm. Multiple fixed versions available.
- Record
ROOT-APP-NPM-CVE-2026-33940- CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H - Updated
- 2026-11-02
OSVROOT-APP-NPM-GHSA-7rx3-28cr-v5wh
4.8
GHSA-7rx3-28cr-v5wh in handlebars - Patched by Root
Root has patched GHSA-7rx3-28cr-v5wh in the handlebars package for Root:npm. Multiple fixed versions available.
- Record
ROOT-APP-NPM-GHSA-7rx3-28cr-v5wh- CVSS 3.1
- 4.8 Medium
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N - Updated
- 2026-11-02
OSVUBUNTU-CVE-2026-33940
8.1
Handlebars provides the power necessary to let users build semantic templates. In versions 4.0.0 through 4.7.8, 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. Version 4.7.9 fixes the issue. Some workarounds are available. First, use the runtime-only build (require('handlebars/runtime')). Without compile(), the fallback compilation path in invokePartial is unreachable. Second, sanitize context data before rendering: Ensure no value in the context is a non-primitive object that could be passed to a dynamic partial. Third, avoid dynamic partial lookups ({{> (lookup ...)}}) when context data is user-controlled.
- Record
UBUNTU-CVE-2026-33940- CVSS 3.1
- 8.1 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H - Updated
- 2026-11-02
OSVCLSA-2026-1777163884 No score
TuxCare security update for handlebars (2 CVEs)
TuxCare rebuilt handlebars to address 2 CVEs. Fixed in 3.0.3-tuxcare.2.
- Record
CLSA-2026-1777163884- Updated
- 2026-11-02
OSVCLSA-2026-1782349135 No score
TuxCare security update for handlebars (8 CVEs)
TuxCare rebuilt handlebars to address 8 CVEs. Fixed in 4.7.7-tuxcare.1.
- Record
CLSA-2026-1782349135- Updated
- 2026-11-02
OSVCLSA-2026-1782435546 No score
TuxCare security update for handlebars (8 CVEs)
TuxCare rebuilt handlebars to address 8 CVEs. Fixed in 4.7.8-tuxcare.1.
- Record
CLSA-2026-1782435546- Updated
- 2026-11-02
OSVCLSA-2026-1785117463 No score
TuxCare security update for handlebars (5 CVEs)
TuxCare rebuilt handlebars to address 5 CVEs. Fixed in 3.0.8-tuxcare.3.
- Record
CLSA-2026-1785117463- Updated
- 2026-11-02
OSVCLSA-2026-1787070403 No score
TuxCare security update for handlebars (2 CVEs)
TuxCare rebuilt handlebars to address 2 CVEs. Fixed in 2.0.0-tuxcare.5.
- Record
CLSA-2026-1787070403- Updated
- 2026-11-02
OSVCLSA-2026-1792139237 No score
TuxCare security update for handlebars (7 CVEs)
TuxCare rebuilt handlebars to address 7 CVEs. Fixed in 4.5.3-tuxcare.3.
- Record
CLSA-2026-1792139237- Updated
- 2026-11-02
Affected products
- handlebars-lang handlebars.js
- handlebarsjs handlebars
- red hat cluster observability operator 1.5.0
- red hat cryostat 4
- red hat logging subsystem for red hat openshift
- red hat data grid 8
- red hat enterprise linux 10
- red hat enterprise linux 7
- red hat enterprise linux 8
- red hat enterprise linux 9
- red hat openshift ai (rhoai)
- red hat openshift dev spaces 3.27
Show 1 moreShow less
Affected packages
| Package | Affected | Fixed |
|---|---|---|
handlebarsnpm |
4.0.0 to 4.7.8 | 4.7.9 |
handlebarsnpm |
4.6.0 to 4.7.8 | 4.7.9 |
handlebarsTuxCare:npm From an advisory covering 2 CVEs |
3.0.3-tuxcare.0 up to 3.0.3-tuxcare.2, plus listed versions 3.0.33.0.3-tuxcare.1 |
3.0.3-tuxcare.2 |
handlebarsTuxCare:npm From an advisory covering 6 CVEs |
4.7.7-tuxcare.0 up to 4.7.7-tuxcare.1, plus listed versions 4.7.7 |
4.7.7-tuxcare.1 |
handlebarsTuxCare:npm From an advisory covering 6 CVEs |
4.7.8-tuxcare.0 up to 4.7.8-tuxcare.1, plus listed versions 4.7.8 |
4.7.8-tuxcare.1 |
handlebarsTuxCare:npm From an advisory covering 4 CVEs |
3.0.8-tuxcare.0 up to 3.0.8-tuxcare.3, plus listed versions 3.0.83.0.8-tuxcare.13.0.8-tuxcare.2 |
3.0.8-tuxcare.3 |
handlebarsTuxCare:npm From an advisory covering 2 CVEs |
2.0.0-tuxcare.0 up to 2.0.0-tuxcare.5, plus listed versions 2.0.02.0.0-tuxcare.12.0.0-tuxcare.22.0.0-tuxcare.32.0.0-tuxcare.4 |
2.0.0-tuxcare.5 |
handlebarsTuxCare:npm From an advisory covering 6 CVEs |
4.5.3-tuxcare.0 up to 4.5.3-tuxcare.3, plus listed versions 4.5.34.5.3-tuxcare.14.5.3-tuxcare.2 |
4.5.3-tuxcare.3 |
node-handlebarsDebian:12 |
All versions, plus listed versions 3:4.7.10-13:4.7.7+~4.1.0-13:4.7.9-13:4.7.9-23:4.7.9-33:4.7.9-43:4.7.9-53:4.7.9-6 |
None known |
node-handlebarsDebian:13 |
All versions, plus listed versions 3:4.7.10-13:4.7.7+~4.1.0-13:4.7.9-13:4.7.9-23:4.7.9-33:4.7.9-43:4.7.9-53:4.7.9-6 |
None known |
Show 14 moreShow less
| Package | Affected | Fixed |
|---|---|---|
node-handlebarsDebian:14 |
before 3:4.7.9-1, plus listed versions 3:4.7.7+~4.1.0-1 |
3:4.7.9-1 |
handlebarsnpm |
4.0.0 up to 4.7.9 | 4.7.9 |
handlebarsnpm |
4.6.0 up to 4.7.9 | 4.7.9 |
handlebarsRoot:npm |
before 4.7.7-aikido.2 | 4.7.7-aikido.24.7.8-aikido.64.7.7-aikido.34.7.7-aikido.44.7.7-aikido.5 |
@rootio/handlebarsRoot:npm |
before 4.7.8-root.io.2 | 4.7.8-root.io.24.7.8-root.io.34.7.8-root.io.44.7.8-root.io.54.7.7-root.io.14.7.7-root.io.24.7.8-root.io.64.7.7-root.io.34.7.7-root.io.44.7.7-root.io.5 |
handlebarsRoot:npm |
before 4.7.8-aikido.6 | 4.7.8-aikido.64.7.7-aikido.34.7.7-aikido.44.7.7-aikido.5 |
@rootio/handlebarsRoot:npm |
before 4.7.8-root.io.5 | 4.7.8-root.io.54.7.8-root.io.64.7.7-root.io.34.7.7-root.io.44.7.7-root.io.5 |
node-handlebarsUbuntu:18.04:LTS |
All versions, plus listed versions 3:4.0.10-5 |
None known |
node-handlebarsUbuntu:20.04:LTS |
All versions, plus listed versions 3:4.1.0-13:4.5.3-13:4.7.2-1 |
None known |
node-handlebarsUbuntu:22.04:LTS |
All versions, plus listed versions 3:4.7.6+~4.1.0-23:4.7.7+~4.1.0-1 |
None known |
node-handlebarsUbuntu:24.04:LTS |
All versions, plus listed versions 3:4.7.7+~4.1.0-1 |
None known |
node-handlebarsUbuntu:25.10 |
All versions, plus listed versions 3:4.7.7+~4.1.0-1 |
None known |
node-handlebarsUbuntu:26.10 |
All versions, plus listed versions 3:4.7.7+~4.1.0-13:4.7.9-5 |
None known |
node-handlebarsUbuntu:26.04:LTS |
All versions, plus listed versions 3:4.7.7+~4.1.0-1 |
None known |
History
| Recorded | Changed | Sources |
|---|---|---|
| affected, facts | ||
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-33940 is a high vulnerability (CVSS 8.1) in Handlebars-lang Handlebars.js, published March 27, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.71%, the 53rd percentile. Fixed in handlebars 4.7.9.
References
github.com/handlebars-lang/handlebars.js/security/advisories/GHSA-xhpv-hc6g-r9c6
github.com/handlebars-lang/handlebars.js/commit/68d8df5a88e0a26fe9e6084c5c6aaebe67b07da2
github.com/handlebars-lang/handlebars.js/releases/tag/v4.7.9
access.redhat.com/security/cve/CVE-2026-33940
bugzilla.redhat.com/show_bug.cgi?id=2452521
security.access.redhat.com/data/csaf/v2/vex/2026/cve-2026-33940.json
Show 14 moreShow less
access.redhat.com/errata/RHSA-2026:34342
access.redhat.com/errata/RHSA-2026:10175
github.com/handlebars-lang/handlebars.js/security/advisories/GHSA-442j-39wm-28r2
github.com/advisories/GHSA-442j-39wm-28r2
github.com/handlebars-lang/handlebars.js/security/advisories/GHSA-7rx3-28cr-v5wh
github.com/advisories/GHSA-765h-qjxv-5f44
github.com/advisories/GHSA-7rx3-28cr-v5wh
nvd.nist.gov/vuln/detail/CVE-2026-33940
github.com/advisories/GHSA-xhpv-hc6g-r9c6
github.com/CVEProject/cvelistV5/tree/main/cves/2026/33xxx/CVE-2026-33940.json
security-tracker.debian.org/tracker/CVE-2026-33940
github.com/handlebars-lang/handlebars.js
ubuntu.com/security/CVE-2026-33940
cve.org/CVERecord?id=CVE-2026-33940