Cloudanix VulnDB

GHSA-2cf5-4w76-r9qv

High · 7.3

CVSS

7.3

EPSS

—

Published

Sep 4, 2020

CISA due date

—

Cloudanix analysis

Next patch cycle SSVC: Track

A vulnerable template library can let someone who can edit templates make the application run their own code on the server.

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

What it actually does

This vulnerability affects the npm handlebars template engine and can permit arbitrary code execution when an application compiles or renders attacker-controlled Handlebars templates. The issue is a sandbox-escape class flaw: specially crafted template expressions can reach JavaScript object constructors or helper behavior that should not be exposed to templates, allowing execution of attacker-supplied JavaScript in the context of the Node.js process. Impact depends on how the library is used; applications that only render trusted, developer-controlled templates are much less exposed, while systems that accept user-supplied templates, themes, email templates, document templates, CMS snippets, or plugin-defined templates are at higher risk.

Why it matters to the business

Successful exploitation can let an attacker take over the application process, read or modify application data, access secrets available to the runtime, pivot to connected services, or disrupt service availability. Because Handlebars is a widely used npm package and this issue has been public for years, organizations should assume vulnerable versions are well understood by attackers even though this advisory is not listed in CISA KEV and has no indicated ransomware association.

How an attack unfolds

An attacker first needs a path to influence a Handlebars template, not merely the normal data values inserted into a safe template. Common exposure points include user-editable notification templates, CMS/theme functionality, report builders, document-generation workflows, low-code customization, or administrative template-preview features. The attacker submits a crafted Handlebars template that abuses expression resolution and JavaScript object access to escape the intended template sandbox. When the vulnerable application compiles or renders that template with an affected handlebars version, the payload can execute JavaScript inside the Node.js runtime. From there, the attacker may run system commands if the process permits it, read environment variables, access credentials, make outbound network connections, alter rendered content, or establish persistence through modified templates or application files.

How to fix it

Upgrade handlebars to a fixed version. For the npm package, use handlebars 3.0.8 or later on the 3.x line, or handlebars 4.5.2 or later on the 4.x line. Prefer upgrading to the latest supported release compatible with the application. After upgrading, regenerate lockfiles and rebuild/redeploy artifacts so vulnerable transitive copies are removed. If immediate upgrade is not possible, mitigate by preventing untrusted users from creating, editing, importing, or previewing Handlebars templates; restrict template customization to trusted administrators; disable dynamic template compilation where feasible; precompile trusted templates during build time; run the Node.js service with least privilege; block unnecessary outbound network access from the application; and ensure secrets are not exposed unnecessarily through environment variables or process-accessible files.

How to confirm the fix worked

Confirm dependency resolution with package-manager tooling such as `npm ls handlebars`, `npm audit`, `yarn why handlebars`, `pnpm why handlebars`, or software composition analysis results. Verify that every resolved handlebars instance is 3.0.8 or later for 3.x, or 4.5.2 or later for 4.x, and that no vulnerable copy remains in nested dependencies or bundled application artifacts. Review lockfiles such as `package-lock.json`, `yarn.lock`, or `pnpm-lock.yaml` for vulnerable versions. Functionally test template-rendering features after upgrade. For exposure validation, inventory features that allow users, administrators, plugins, or integrations to submit or edit templates, and confirm untrusted template compilation is disabled or restricted.

Typical attack path

  1. Identify an application feature that accepts or stores custom Handlebars templates, themes, snippets, email layouts, document templates, or template-preview content.
  2. Submit benign template expressions to confirm that Handlebars syntax is evaluated server-side.
  3. Craft a malicious template that attempts to escape Handlebars' intended execution constraints and reach JavaScript runtime capabilities.
  4. Trigger rendering or preview of the malicious template so the server compiles and executes it using a vulnerable handlebars package.
  5. Execute commands or JavaScript in the context of the Node.js application process.
  6. Collect secrets, application data, environment variables, or service credentials available to that process.
  7. Use obtained access to move laterally, modify templates or application content, deploy additional payloads, or disrupt service operations.

How to detect it

Investigate whether any application feature allowed untrusted or semi-trusted users to submit Handlebars templates before the fixed version was deployed. Review application logs, template-edit audit logs, CMS/theme/plugin logs, request bodies captured by WAF or API gateways, and database-backed template histories for suspicious Handlebars expressions referencing JavaScript internals, constructors, module loading, process access, or command execution. On hosts and containers, review process telemetry for unexpected child processes spawned by Node.js, such as shells, curl/wget, PowerShell, Python, Perl, or netcat. Examine EDR, container runtime, and operating-system logs for Node.js processes invoking command interpreters or making unusual outbound network connections. Review web access logs for requests to template-preview, template-save, theme, email-template, notification-template, report-template, or document-generation endpoints followed by errors, outbound callbacks, new processes, or changes to stored templates. Because no single universal IOC exists for this library flaw, prioritize behavioral evidence: malicious template content, unexpected Node.js child processes, credential access, and suspicious outbound traffic after template rendering.

  • constructor.constructor
  • process.mainModule
  • require('child_process')
  • require("child_process")
  • child_process.exec
  • child_process.execSync
  • child_process.spawn
  • execSync(
  • Function("return this")
  • Function('return this')
  • {{lookup
  • __proto__
  • prototype.constructor
  • process.env
  • /bin/sh -c
  • cmd.exe /c
  • powershell.exe
  • curl http://
  • wget http://
  • nc -e
  • bash -i

What your security team should do

  • Prioritize upgrading all applications and build artifacts that include vulnerable handlebars versions, especially internet-facing services and systems with user-editable templates.
  • Search dependency inventories, lockfiles, container images, serverless packages, and frontend/backend bundles for handlebars versions older than the fixed releases.
  • Identify application features that compile templates dynamically and restrict them to trusted users or replace them with precompiled, developer-controlled templates.
  • Review historical template content and template-edit audit logs for suspicious JavaScript runtime access patterns.
  • Harden Node.js runtime permissions: run as a non-root user, minimize filesystem access, restrict outbound egress, and avoid exposing high-value secrets through environment variables where possible.
  • Add detection for suspicious Handlebars template strings that reference JavaScript constructors, process access, child process execution, or module loading.
  • If suspicious exploitation is found, rotate credentials accessible to the affected process, preserve forensic artifacts, and investigate outbound connections and child processes spawned by the application.

The record

Arbitrary Code Execution in handlebars

Affected packages

Ecosystem Package Introduced Fixed
npm handlebars 0 3.0.8
npm handlebars 4.0.0 4.5.2
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
Wolfi code-server 0 0
Wolfi code-server-compat 0 0

Related vulnerabilities