Cloudanix VulnDB

CVE-2026-33937

Critical · 9.8

CVSS

9.8

EPSS

1.7%

Published

Mar 27, 2026

CISA due date

—

Cloudanix analysis

Next patch cycle SSVC: Track

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

  1. Identify an application endpoint, workflow, plugin, CMS feature, email/template builder, report generator, or API that uses server-side Handlebars template compilation.
  2. Determine whether attacker-controlled input can reach `Handlebars.compile()` as an object or JSON-deserialized value rather than as a plain template string.
  3. Submit a crafted Handlebars AST object containing a malicious `NumberLiteral.value` payload.
  4. Trigger server-side compilation or rendering of the submitted template object.
  5. Achieve JavaScript execution in the Node.js process running the application.
  6. Use the application process privileges to read secrets, access files, call internal services, execute operating system commands where possible, or disrupt the service.
  7. 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