Media

Handlebars.js has Prototype Pollution Leading to XSS through Partial Template Injection

  • Publicada: 26.03.2026
  • Actualizado: 11.10.2026 10:22

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

js
// 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

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

Software afectado

Haz clic en una tecnología para ver todas sus vulnerabilidades.

PlataformaPaqueteVersiones vulnerablesCorregida en
Paquete de npm handlebars >= 4.0.0, < 4.7.9 4.7.9

Referencias

Puntuación CVSS 4.7/10
Vector CVSS
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:L/I:L/A:N
Debilidad (CWE)
CWE-1321, CWE-79
Plataforma
npm
Paquete
handlebars
Publicada
26.03.2026
Actualizado
11.10.2026 10:22

Fuentes y licencias

OSV / GitHub Advisory Database - GHSA-2qvq-rjwj-gvw9 - CC BY 4.0

Historial de vulnerabilidades: handlebars

Todas las vulnerabilidades publicadas de este paquete (Paquete de npm), de la más reciente a la más antigua. Muestra si es un fallo aislado o un paquete que hay que vigilar.

Todas (22) en el archivo
Entradas en total
22
Primera → última
10.2018 10.2026
Sin corrección
0
Explotada en ataques
0

Distribución por gravedad

  • Crítica 6
  • Alta 10
  • Media 5
  • Baja 1

Divulgaciones por año

  1. 2018: 1
  2. 2019: 2
  3. 2020: 4
  4. 2021: 1
  5. 2022: 3
  6. 2023: 0
  7. 2024: 0
  8. 2025: 0
  9. 2026: 11
Gravedad:
  1. Crítica CVE-2026-106445 >= 3.0.0, < 4.7.10 4.7.10
  2. Crítica · 9.8 CVE-2026-33937 >= 4.0.0, < 4.7.9 4.7.9
  3. Handlebars.js has Prototype Pollution Leading to XSS through Partial Template Injection esta entrada
    Media · 4.7 CVE-2026-33916 >= 4.0.0, < 4.7.9 4.7.9
  4. Crítica · 9.8 CVE-2021-23383 < 4.7.7 4.7.7
  5. Alta · 7.5 CVE-2019-20922 >= 4.0.0, < 4.4.5 4.4.5
  6. Alta · 8.1 CVE-2019-20920 < 3.0.8, >= 4.0.0, < 4.5.3 3.0.8, 4.5.3
  7. Crítica · 9.8 CVE-2021-23369 < 4.7.7 4.7.7
  8. Alta ghsa-q2c6-c6pm-g3gh < 3.0.8, >= 4.0.0, < 4.5.3 3.0.8, 4.5.3
  9. Alta ghsa-g9r4-xpmj-mj65 < 3.0.8, >= 4.0.0, < 4.5.3 3.0.8, 4.5.3
  10. Alta · 7.3 ghsa-2cf5-4w76-r9qv < 3.0.8, >= 4.0.0, < 4.5.2 3.0.8, 4.5.2
  11. Crítica · 9.8 CVE-2019-19919 >= 4.0.0, < 4.3.0, < 3.0.8 4.3.0, 3.0.8
  12. Alta · 7.3 ghsa-q42p-pg8m-cqh6 >= 4.1.0, < 4.1.2, >= 4.0.0, < 4.0.14, < 3.0.7 4.1.2, 4.0.14, 3.0.7

Identifica las vulnerabilidades de tu aplicación

Con la integración de DockRay y el inventario de software activado, DockRay compara las versiones notificadas de los componentes con las vulnerabilidades conocidas y avisa de las coincidencias confirmadas. La cobertura depende de la tecnología compatible y de los avisos disponibles.

Conectar tu aplicación
Newsletter DockRay

La seguridad de tus aplicaciones en tu correo

Vulnerabilidades importantes, recomendaciones concretas y consejos prácticos para tus aplicaciones. Elige tus tecnologías y sigue lo que importa para tu proyecto.

  • Un resumen diario de nuevas vulnerabilidades, también las críticas.
  • Avisos sobre actualizaciones importantes.
  • Consejos prácticos sobre seguridad y monitorización de aplicaciones.

Déjalo vacío para recibir avisos de todas las tecnologías.

Suscripción gratuita. Date de baja con un clic en cualquier correo.