GHSA-442j-39wm-28r2 Handlebars.js has a Property Access Validation Bypass in container.lookup

Not scored Published

Attackers can bypass prototype access controls in Handlebars.js when compat mode is enabled, potentially reading restricted properties from context objects.

Exploited in the wild
Not known
Login needed
Not needed
Attackable
Over the internet
Victim action needed
Not needed
Fix
Available

What is GHSA-442j-39wm-28r2?

GHSA-442j-39wm-28r2 is a vulnerability in handlebars, published on 29 Mar 2026. An attacker can exploit it over the internet without logging in, with no action from the victim.

Official 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):

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).

Which versions are affected by GHSA-442j-39wm-28r2?

2 open source packages ship an affected version, including handlebars.

PackageAffectedFixed in
handlebars npmFrom 4.0.04.7.9
handlebars npmFrom 4.0.04.7.9

How do I fix GHSA-442j-39wm-28r2?

Upgrade handlebars to 4.7.9 or later.

Is GHSA-442j-39wm-28r2 being exploited?

There is no known exploitation of GHSA-442j-39wm-28r2 in the wild and no public exploit code.

Sources

Is GHSA-442j-39wm-28r2 in your software?

Upload an SBOM and sbomify checks it against every vulnerability here, every day.

Check your SBOMs for free