CVE-2026-33937
Critical · 9.8CVSS
9.8
EPSS
1.7%
Published
Mar 27, 2026
CISA due date
—
Cloudanix analysis
A flaw in a common template library can let an attacker run their own code on a server if the application accepts specially crafted template data.
- Exploitation
- Remote Unauthenticated
- Attacker needs
- None
- Complexity
- Low
- Impact
- Remote Code Execution
- Component
- Library
- Class
- RCE
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
CVE-2026-33937 is a server-side remote code execution vulnerability in Handlebars versions 4.0.0 through 4.7.8. The vulnerable behavior occurs when `Handlebars.compile()` is called with a pre-parsed AST object instead of a template string. For `NumberLiteral` AST nodes, the `value` field is emitted directly into generated JavaScript without proper quoting or sanitization. If an attacker can cause an application to pass attacker-controlled JSON or a plain object into `Handlebars.compile()`, they can inject arbitrary JavaScript into the compiled template function and execute code in the context of the server-side Node.js process. Successful exploitation can compromise confidentiality, integrity, and availability of the application and any resources accessible to that process.
Why it matters to the business
An affected application that compiles attacker-controlled template objects may allow an unauthenticated remote attacker to run commands on the server. This can lead to theft of application secrets, access tokens, customer data, source code, or connected backend systems; modification of rendered content or business logic; installation of malware; lateral movement; and service disruption. Although this CVE is not currently listed in CISA KEV and no mature public exploit is indicated in the provided data, the CVSS score is critical and the affected package is widely used in JavaScript ecosystems, so organizations should treat exposure as high priority where server-side `Handlebars.compile()` may receive untrusted input.
How an attack unfolds
An attacker first identifies an application feature or API path that accepts, stores, or transforms user-provided template data and eventually passes it to `Handlebars.compile()`. Instead of submitting a normal template string, the attacker submits a crafted object that resembles a Handlebars AST, often via JSON. The malicious AST contains a `NumberLiteral` node whose `value` field is not a normal number but JavaScript source intended to break into the generated template function. In vulnerable Handlebars versions, the compiler emits this field directly into JavaScript. When the server compiles or renders the template, the injected JavaScript executes inside the Node.js process. From there, the attacker may read environment variables, access files, execute child processes if available, open outbound network connections, deploy persistence, or use the compromised application’s privileges to reach internal services.
How to fix it
Upgrade Handlebars to version 4.7.9 or later wherever `handlebars` is used. If package-level fixed versions are managed through lockfiles, regenerate and redeploy the lockfile after updating so transitive copies are also resolved to a fixed version. As a defensive workaround, validate the input type before every call to `Handlebars.compile()` and reject anything that is not a string; do not pass plain objects, parsed JSON, or user-controlled ASTs to `compile()`. If templates are precompiled during build or deployment, use the runtime-only package path `handlebars/runtime` on servers so `compile()` is unavailable at runtime. Restrict or remove user-controlled template authoring where possible, sandbox template processing if it must exist, and run Node.js services with least privilege, constrained filesystem access, restricted outbound network access, and no unnecessary shell utilities or cloud credentials.
How to confirm the fix worked
Confirm that all deployed applications and build artifacts use Handlebars 4.7.9 or later by checking `package-lock.json`, `yarn.lock`, `pnpm-lock.yaml`, SBOMs, container images, and runtime dependency inventories. Search code for `Handlebars.compile(`, `.compile(` on Handlebars instances, or imports from `handlebars`, then verify the argument is always a string and cannot be a JSON-deserialized object. Confirm server deployments use `handlebars/runtime` when templates are precompiled. Test exposed template-related endpoints with benign non-string JSON input and verify it is rejected before reaching Handlebars. In CI/CD, add dependency scanning and unit tests that fail if vulnerable Handlebars versions are reintroduced or if `compile()` accepts object input.
Typical attack path
- Identify an application endpoint, workflow, plugin, CMS feature, email/template builder, report generator, or API that uses server-side Handlebars template compilation.
- Determine whether attacker-controlled input can reach `Handlebars.compile()` as an object or JSON-deserialized value rather than as a plain template string.
- Submit a crafted Handlebars AST object containing a malicious `NumberLiteral.value` payload.
- Trigger server-side compilation or rendering of the submitted template object.
- Achieve JavaScript execution in the Node.js process running the application.
- Use the application process privileges to read secrets, access files, call internal services, execute operating system commands where possible, or disrupt the service.
- Clean up artifacts or establish persistence depending on attacker objectives.
How to detect it
To determine whether exploitation has already occurred, review application access logs for endpoints that accept templates, rendering definitions, email layouts, report definitions, CMS content, or JSON configuration objects. Look for requests containing Handlebars AST structures rather than normal template strings, especially JSON fields such as `type`, `NumberLiteral`, `Program`, `body`, `value`, `loc`, or `path`. Review application logs for template compilation failures, syntax errors in generated JavaScript, unexpected Handlebars parser/compiler exceptions, and crashes around template rendering. On hosts and containers running affected Node.js services, correlate suspicious requests with process telemetry showing `node` spawning shells or utilities such as `sh`, `bash`, `cmd.exe`, `powershell.exe`, `curl`, `wget`, `nc`, `python`, or `perl`. Inspect EDR, auditd, Sysmon, container runtime, and cloud workload logs for unexpected file reads, writes to temporary directories, outbound connections, credential access, or environment variable dumping by the Node.js process. Review package manager and deployment timelines to identify whether vulnerable Handlebars versions were present during suspicious activity. Because payloads are application-specific and no universal exploit string is provided, prioritize behavioral detections around attacker-controlled AST submission and anomalous child processes from Node.js application workers.
- "NumberLiteral"
- "Handlebars.compile"
- "type":"NumberLiteral"
- "type":"Program"
- "value":"process"
- "value":"require"
- "value":"child_process"
- "child_process"
- "process.env"
- "constructor.constructor"
- "Cannot read properties of undefined"
- "SyntaxError: Unexpected token"
- "SyntaxError: Invalid or unexpected token"
- "Error: Parse error"
- "node" spawning "sh"
- "node" spawning "bash"
- "node" spawning "cmd.exe"
- "node" spawning "powershell.exe"
- "node" spawning "curl"
- "node" spawning "wget"
- "node" spawning "nc"
- "/tmp/"
- "/var/tmp/"
What your security team should do
- Prioritize inventory of all applications, containers, serverless functions, and build pipelines using `handlebars` versions 4.0.0 through 4.7.8.
- Upgrade to Handlebars 4.7.9 or later and redeploy affected services; verify lockfiles and container images no longer include vulnerable versions.
- Review all uses of `Handlebars.compile()` and enforce strict string-only input validation immediately before the call site.
- Disable runtime template compilation where possible and switch production services to `handlebars/runtime` with precompiled templates.
- Investigate externally reachable template-authoring, rendering, document-generation, notification, CMS, and reporting features for possible attacker-controlled AST submission.
- Add WAF/API validation rules to reject unexpected JSON objects in endpoints that should accept only template strings or identifiers.
- Harden Node.js runtime permissions, secrets access, egress, and service account privileges to reduce post-exploitation impact.
- Search recent logs and telemetry for suspicious template compilation errors, JSON payloads containing Handlebars AST node types, and Node.js child process execution from application services.
- Add dependency policy gates to prevent deployment of Handlebars versions below 4.7.9.
The record
Handlebars provides the power necessary to let users build semantic templates. In versions 4.0.0 through 4.7.8, `Handlebars.compile()` accepts a pre-parsed AST object in addition to a template string. The `value` field of a `NumberLiteral` AST node is emitted directly into the generated JavaScript without quoting or sanitization. An attacker who can supply a crafted AST to `compile()` can therefore inject and execute arbitrary JavaScript, leading to Remote Code Execution on the server. Version 4.7.9 fixes the issue. Some workarounds are available. Validate input type before calling `Handlebars.compile()`; ensure the argument is always a `string`, never a plain object or JSON-deserialized value. Use the Handlebars runtime-only build (`handlebars/runtime`) on the server if templates are pre-compiled at build time; `compile()` will be unavailable.
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-2w6w-674q-4c4q Handlebars.js has JavaScript Injection via AST Type Confusion 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-33941 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-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