Cloudanix VulnDB

CVE-2019-19919

Critical · 9.8

CVSS

9.8

EPSS

7.1%

Published

Dec 20, 2019

CISA due date

—

Cloudanix analysis

Next patch cycle SSVC: Track

Some applications using older Handlebars software can be tricked into running attacker commands if they process templates supplied by untrusted users.

Exploitation
Remote Unauthenticated
Attacker needs
None
Complexity
Low
Impact
Remote Code Execution
Component
Library
Class
Improper Input Validation
Remediation
Upgrade
Effort
Medium
Patch risk
Low

What it actually does

CVE-2019-19919 affects Handlebars versions prior to 4.3.0 and allows prototype pollution through unsafe handling of template-controlled properties such as __proto__ and __defineGetter__. If an attacker can supply or influence a Handlebars template or template input in an application that compiles or renders untrusted templates, they may modify JavaScript object prototypes and influence downstream property lookups. In vulnerable usage patterns, this can be chained to arbitrary JavaScript execution in the Node.js process, resulting in remote code execution with the privileges of the affected application.

Why it matters to the business

Successful exploitation can allow an unauthenticated remote attacker to run code on servers that process attacker-controlled Handlebars templates, potentially leading to application takeover, data theft, service disruption, credential exposure, and lateral movement from the compromised runtime. Although this issue is not listed in CISA KEV and the provided exploit maturity is none, the vulnerability is high severity and affects a widely used JavaScript templating library that may be embedded in many downstream applications, including products that bundle Handlebars such as Tenable.sc.

How an attack unfolds

An attacker first identifies an application or product path that uses a vulnerable Handlebars version and accepts template content, template partials, helper definitions, or otherwise attacker-influenced values that are compiled or rendered by Handlebars. The attacker submits a crafted payload that references special JavaScript object properties such as __proto__ or __defineGetter__ to pollute Object.prototype or alter getter behavior. Once the runtime's prototype chain is modified, subsequent application logic may resolve attacker-controlled properties or execute attacker-influenced functions. In vulnerable configurations, the attacker can use this primitive to escape intended template restrictions and trigger arbitrary JavaScript execution in the server-side Node.js process. The impact depends heavily on whether the application exposes untrusted template rendering; applications that only render trusted, static templates are significantly less exposed.

How to fix it

Upgrade Handlebars to version 4.3.0 or later wherever it is used directly or bundled transitively. Because this is a library vulnerability, review package-lock.json, yarn.lock, pnpm-lock.yaml, npm-shrinkwrap.json, and container images to identify transitive or vendored copies of handlebars. If an affected commercial product bundles Handlebars, apply the vendor-supplied fixed release or security patch rather than attempting to replace the embedded library manually. As defense in depth, do not compile or render untrusted Handlebars templates; treat user-provided templates, report definitions, email templates, and plugin-supplied templates as code. Restrict or disable user-controlled helpers, sandbox template execution where possible, run Node.js services with least privilege, and prevent template rendering processes from accessing secrets or sensitive filesystem paths unnecessarily.

How to confirm the fix worked

Confirm all deployed applications and build artifacts use Handlebars 4.3.0 or later by checking package manifests and lockfiles with commands such as npm ls handlebars, yarn why handlebars, pnpm why handlebars, and software composition analysis tools. Inspect container images and deployed bundles for embedded node_modules/handlebars/package.json files showing versions prior to 4.3.0. Exercise any features that accept user-supplied templates and verify they are disabled, restricted to trusted users, or rendered in a hardened sandbox. Run dependency scanning in CI/CD and against production images to ensure no vulnerable transitive dependency remains. For vendor appliances or bundled products, verify the installed version matches the vendor advisory for a fixed release.

Typical attack path

  1. Identify a web application, API, build system, reporting feature, email templating feature, plugin system, or bundled product that uses Handlebars prior to 4.3.0.
  2. Find an input path where the attacker can control template content, partials, helpers, or data that is compiled or interpreted as a Handlebars template.
  3. Submit a crafted Handlebars payload using prototype-related properties such as __proto__ or __defineGetter__.
  4. Pollute JavaScript object prototypes or alter getter behavior within the Node.js runtime.
  5. Chain the polluted prototype state into template evaluation or application logic to execute arbitrary JavaScript.
  6. Use code execution to read sensitive files or environment variables, modify application behavior, deploy a web shell or backdoor, or pivot to additional systems.

How to detect it

To determine whether exploitation already occurred, review application access logs, API gateway logs, reverse proxy logs, WAF events, and request bodies for Handlebars expressions containing prototype-pollution or JavaScript execution primitives. Look for strings such as __proto__, __defineGetter__, constructor, prototype, lookup, with, blockHelperMissing, and suspicious nested Handlebars syntax in parameters that normally contain templates, report definitions, email bodies, or JSON configuration. On affected Node.js servers, review process telemetry and EDR logs for unexpected child processes spawned by node, including sh, bash, dash, cmd.exe, powershell.exe, curl, wget, nc, ncat, python, perl, or node subprocesses. Inspect application logs for template compilation errors, unusual helper resolution failures, TypeError or ReferenceError messages involving prototype properties, and crashes around Handlebars rendering. Review filesystem changes for newly created scripts, web-accessible files, modified package files, or persistence artifacts written by the Node.js service account. If telemetry is available, correlate suspicious template requests with outbound network connections, DNS lookups, credential access, environment variable dumping, or reads of sensitive files such as .env, configuration files, SSH keys, or cloud credential files. Because there are no universally unique exploit artifacts for this library issue, detection should focus on suspicious template payloads plus post-exploitation behavior from the Node.js process.

  • __proto__
  • __defineGetter__
  • constructor.prototype
  • Object.prototype
  • {{__proto__
  • {{#with
  • {{#lookup
  • blockHelperMissing
  • Handlebars.compile
  • Handlebars.precompile
  • node_modules/handlebars/package.json
  • node_modules/handlebars/dist/handlebars.js
  • node_modules/handlebars/lib/handlebars
  • node_modules/handlebars/package.json: "version": "4.0
  • node_modules/handlebars/package.json: "version": "4.1
  • node_modules/handlebars/package.json: "version": "4.2
  • node child process: /bin/sh
  • node child process: /bin/bash
  • node child process: cmd.exe
  • node child process: powershell.exe

What your security team should do

  • Inventory all applications, services, containers, serverless functions, CI jobs, and vendor products that include Handlebars, prioritizing internet-facing systems and features that render user-controlled templates.
  • Upgrade Handlebars to 4.3.0 or later, or apply the relevant vendor patch for products that bundle the library.
  • Search source code for server-side template compilation of untrusted input, especially use of Handlebars.compile, Handlebars.precompile, dynamic partials, custom helpers, and user-editable template features.
  • Block or tightly restrict user-provided templates; where business requirements require them, isolate rendering in a sandboxed process with minimal privileges and no access to production secrets.
  • Add dependency-scanning gates to CI/CD to prevent reintroduction of handlebars versions prior to 4.3.0.
  • Review logs and telemetry for suspicious template payloads, prototype pollution strings, unexpected child process execution from Node.js services, and abnormal outbound connections.
  • Rotate credentials and secrets accessible to any Node.js service where exploitation is suspected, because successful exploitation may expose environment variables and local configuration files.

The record

Versions of handlebars prior to 4.3.0 are vulnerable to Prototype Pollution leading to Remote Code Execution. Templates may alter an Object's __proto__ and __defineGetter__ properties, which may allow an attacker to execute arbitrary code through crafted payloads.

Affected packages

Ecosystem Package Introduced Fixed
RubyGems bootstrap-wysihtml5-rails 0.3.3.5 No fix
npm handlebars 0 3.0.8
npm handlebars 4.0.0 4.3.0
Chainguard code-server 0 0
Chainguard code-server-compat 0 0
Chainguard gitlab-rails-ce-18.1 0 0
Chainguard gitlab-rails-ce-18.2 0 0
Chainguard gitlab-rails-ce-18.3 0 0
Chainguard gitlab-rails-ce-18.4 0 0
Chainguard gitlab-rails-ce-18.5 0 0
Chainguard gitlab-rails-ce-18.6 0 0
Chainguard gitlab-rails-ce-18.7 0 0
Chainguard gitlab-rails-ce-assets-18.1 0 0
Chainguard gitlab-rails-ce-assets-18.2 0 0
Chainguard gitlab-rails-ce-assets-18.3 0 0
Chainguard gitlab-rails-ce-assets-18.4 0 0
Chainguard gitlab-rails-ce-assets-18.5 0 0
Chainguard gitlab-rails-ce-assets-18.6 0 0
Chainguard gitlab-rails-ce-assets-18.7 0 0
Chainguard gitlab-rails-ce-assets-18.8 0 0
Chainguard gitlab-rails-ce-assets-18.9 0 0
Chainguard gitlab-rails-ce-assets-fips-18.1 0 0
Chainguard gitlab-rails-ce-assets-fips-18.2 0 0
Chainguard gitlab-rails-ce-assets-fips-18.3 0 0
Chainguard gitlab-rails-ce-assets-fips-18.4 0 0
Chainguard gitlab-rails-ce-assets-fips-18.5 0 0
Chainguard gitlab-rails-ce-assets-fips-18.6 0 0
Chainguard gitlab-rails-ce-assets-fips-18.7 0 0
Chainguard gitlab-rails-ce-assets-fips-18.8 0 0
Chainguard gitlab-rails-ce-assets-fips-18.9 0 0
Chainguard gitlab-rails-ce-doc-18.1 0 0
Chainguard gitlab-rails-ce-doc-18.2 0 0
Chainguard gitlab-rails-ce-doc-18.3 0 0
Chainguard gitlab-rails-ce-doc-18.4 0 0
Chainguard gitlab-rails-ce-doc-18.5 0 0
Chainguard gitlab-rails-ce-doc-18.6 0 0
Chainguard gitlab-rails-ce-doc-18.7 0 0
Chainguard gitlab-rails-ce-doc-fips-18.1 0 0
Chainguard gitlab-rails-ce-doc-fips-18.2 0 0
Chainguard gitlab-rails-ce-doc-fips-18.3 0 0
Chainguard gitlab-rails-ce-doc-fips-18.4 0 0
Chainguard gitlab-rails-ce-doc-fips-18.5 0 0
Chainguard gitlab-rails-ce-doc-fips-18.6 0 0
Chainguard gitlab-rails-ce-doc-fips-18.7 0 0
Chainguard gitlab-rails-ce-fips-18.1 0 0
Chainguard gitlab-rails-ce-fips-18.2 0 0
Chainguard gitlab-rails-ce-fips-18.3 0 0
Chainguard gitlab-rails-ce-fips-18.4 0 0
Chainguard gitlab-rails-ce-fips-18.5 0 0
Chainguard gitlab-rails-ce-fips-18.6 0 0
Chainguard gitlab-rails-ce-fips-18.7 0 0
Chainguard gitlab-rails-ee-17.0 0 0
Chainguard gitlab-rails-ee-17.1 0 0
Chainguard gitlab-rails-ee-17.10 0 0
Chainguard gitlab-rails-ee-17.11 0 0
Chainguard gitlab-rails-ee-17.2 0 0
Chainguard gitlab-rails-ee-17.3 0 0
Chainguard gitlab-rails-ee-17.4 0 0
Chainguard gitlab-rails-ee-17.6 0 0
Chainguard gitlab-rails-ee-17.7 0 0
Chainguard gitlab-rails-ee-17.8 0 0
Chainguard gitlab-rails-ee-17.9 0 0
Chainguard gitlab-rails-ee-assets-17.10 0 0
Chainguard gitlab-rails-ee-assets-17.11 0 0
Chainguard gitlab-rails-ee-assets-17.2 0 0
Chainguard gitlab-rails-ee-assets-17.3 0 0
Chainguard gitlab-rails-ee-assets-17.4 0 0
Chainguard gitlab-rails-ee-assets-17.6 0 0
Chainguard gitlab-rails-ee-assets-17.7 0 0
Chainguard gitlab-rails-ee-assets-17.8 0 0
Chainguard gitlab-rails-ee-assets-17.9 0 0
Chainguard gitlab-rails-ee-assets-fips-17.10 0 0
Chainguard gitlab-rails-ee-assets-fips-17.11 0 0
Chainguard gitlab-rails-ee-assets-fips-17.2 0 0
Chainguard gitlab-rails-ee-assets-fips-17.3 0 0
Chainguard gitlab-rails-ee-assets-fips-17.4 0 0
Chainguard gitlab-rails-ee-assets-fips-17.6 0 0
Chainguard gitlab-rails-ee-assets-fips-17.7 0 0
Chainguard gitlab-rails-ee-assets-fips-17.8 0 0
Chainguard gitlab-rails-ee-assets-fips-17.9 0 0
Chainguard gitlab-rails-ee-doc-17.10 0 0
Chainguard gitlab-rails-ee-doc-17.11 0 0
Chainguard gitlab-rails-ee-doc-17.2 0 0
Chainguard gitlab-rails-ee-doc-17.3 0 0
Chainguard gitlab-rails-ee-doc-17.4 0 0
Chainguard gitlab-rails-ee-doc-17.6 0 0
Chainguard gitlab-rails-ee-doc-17.7 0 0
Chainguard gitlab-rails-ee-doc-17.8 0 0
Chainguard gitlab-rails-ee-doc-17.9 0 0
Chainguard gitlab-rails-ee-doc-fips-17.10 0 0
Chainguard gitlab-rails-ee-doc-fips-17.11 0 0
Chainguard gitlab-rails-ee-doc-fips-17.2 0 0
Chainguard gitlab-rails-ee-doc-fips-17.3 0 0
Chainguard gitlab-rails-ee-doc-fips-17.4 0 0
Chainguard gitlab-rails-ee-doc-fips-17.6 0 0
Chainguard gitlab-rails-ee-doc-fips-17.7 0 0
Chainguard gitlab-rails-ee-doc-fips-17.8 0 0
Chainguard gitlab-rails-ee-doc-fips-17.9 0 0
Chainguard gitlab-rails-ee-fips-17.0 0 0
Chainguard gitlab-rails-ee-fips-17.1 0 0
Chainguard gitlab-rails-ee-fips-17.10 0 0
Chainguard gitlab-rails-ee-fips-17.11 0 0
Chainguard gitlab-rails-ee-fips-17.2 0 0
Chainguard gitlab-rails-ee-fips-17.3 0 0
Chainguard gitlab-rails-ee-fips-17.4 0 0
Chainguard gitlab-rails-ee-fips-17.6 0 0
Chainguard gitlab-rails-ee-fips-17.7 0 0
Chainguard gitlab-rails-ee-fips-17.8 0 0
Chainguard gitlab-rails-ee-fips-17.9 0 0
Debian:11 node-handlebars 0 3:4.5.3-1
Debian:12 node-handlebars 0 3:4.5.3-1
Debian:13 node-handlebars 0 3:4.5.3-1
Ubuntu:18.04:LTS node-handlebars 0 No fix
Ubuntu:20.04:LTS node-handlebars 0 3:4.5.3-1
Ubuntu:Pro:18.04:LTS node-handlebars 0 No fix
Wolfi code-server 0 0
Wolfi code-server-compat 0 0
gem bootstrap-wysihtml5-rails 0.3.3.5 No fix

Related vulnerabilities