GitHub Advisoryadvisory · npm
GHSA-442j-39wm-28r2 Handlebars.js has a Property Access Validation Bypass in container.lookup
LOW
Official page ↗
- Ecosystem
- npm
- Packages
- handlebars
- Severity
- Low
- CVSS vector
- CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
- Weaknesses
- CWE-367
- Reviewed
- 2026-03-29
Affected packages
• npm handlebars: >= 4.0.0, < 4.7.9 → fixed in 4.7.9
Description
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):
```javascript
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).
Related
Weakness · CWE (1)
- CWE-367 Time-of-check Time-of-use (TOCTOU) Race Condition weakness
References
- https://github.com/handlebars-lang/handlebars.js/security/advisories/GHSA-442j-39wm-28r2 web
- https://github.com/handlebars-lang/handlebars.js/commit/68d8df5a88e0a26fe9e6084c5c6aaebe67b07da2 web
- https://github.com/handlebars-lang/handlebars.js package
- https://github.com/handlebars-lang/handlebars.js/releases/tag/v4.7.9 web