Skip to content

Update dependency handlebars to v4.7.9 [SECURITY]#169

Merged
renovate[bot] merged 1 commit intomainfrom
renovate/npm-handlebars-vulnerability
Mar 27, 2026
Merged

Update dependency handlebars to v4.7.9 [SECURITY]#169
renovate[bot] merged 1 commit intomainfrom
renovate/npm-handlebars-vulnerability

Conversation

@renovate
Copy link
Copy Markdown
Contributor

@renovate renovate Bot commented Mar 26, 2026

This PR contains the following updates:

Package Change Age Confidence
handlebars (source) 4.7.84.7.9 age confidence

GitHub Vulnerability Alerts

CVE-2026-33916

Summary

resolvePartial() in the Handlebars runtime resolves partial names via a plain property lookup on options.partials without guarding against prototype-chain traversal. When Object.prototype has been polluted with a string value whose key matches a partial reference in a template, the polluted string is used as the partial body and rendered without HTML escaping, resulting in reflected or stored XSS.

Description

The root cause is in lib/handlebars/runtime.js inside resolvePartial() and invokePartial():

// Vulnerable: plain bracket access traverses Object.prototype
partial = options.partials[options.name];

hasOwnProperty is never checked, so if Object.prototype has been seeded with a key whose name matches a partial reference in the template (e.g. widget), the lookup succeeds and the polluted string is returned. The runtime emits a prototype-access warning, but the partial is still resolved and its content is inserted into the rendered output unescaped. This contradicts the documented security model and is distinct from CVE-2021-23369 and CVE-2021-23383, which addressed data property access rather than partial template resolution.

Prerequisites for exploitation:

  1. The target application must be vulnerable to prototype pollution (e.g. via qs, minimist, or
    any querystring/JSON merge sink).
  2. The attacker must know or guess the name of a partial reference used in a template.

Proof of Concept

const Handlebars = require('handlebars');

// Step 1: Prototype pollution (via qs, minimist, or another vector)
Object.prototype.widget = '<img src=x onerror="alert(document.domain)">';

// Step 2: Normal template that references a partial
const template = Handlebars.compile('<div>Welcome! {{> widget}}</div>');

// Step 3: Render — XSS payload injected unescaped
const output = template({});
// Output: <div>Welcome! <img src=x onerror="alert(document.domain)"></div>

The runtime prints a prototype access warning claiming "access has been denied," but the partial still resolves and returns the polluted value.

Workarounds

  • Apply Object.freeze(Object.prototype) early in application startup to prevent prototype pollution. Note: this may break other libraries.
  • Use the Handlebars runtime-only build (handlebars/runtime), which does not compile templates and reduces the attack surface.

Release Notes

handlebars-lang/handlebars.js (handlebars)

v4.7.9

Compare Source


Configuration

📅 Schedule: Branch creation - "" (UTC), Automerge - At any time (no schedule defined).

🚦 Automerge: Enabled.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate renovate Bot changed the title Update dependency handlebars to v4.7.9 [SECURITY] Update dependency handlebars to v4.7.9 [SECURITY] - autoclosed Mar 27, 2026
@renovate renovate Bot closed this Mar 27, 2026
@renovate renovate Bot deleted the renovate/npm-handlebars-vulnerability branch March 27, 2026 01:12
@renovate renovate Bot changed the title Update dependency handlebars to v4.7.9 [SECURITY] - autoclosed Update dependency handlebars to v4.7.9 [SECURITY] Mar 27, 2026
@renovate renovate Bot reopened this Mar 27, 2026
@renovate renovate Bot force-pushed the renovate/npm-handlebars-vulnerability branch from 9923a09 to 2927ce1 Compare March 27, 2026 10:03
@renovate renovate Bot merged commit 06b60b8 into main Mar 27, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants