Cloudanix VulnDB

CVE-2026-33940

High · 8.1

CVSS

8.1

EPSS

0.8%

Published

Mar 27, 2026

CISA due date

—

Cloudanix analysis

Next patch cycle SSVC: Track

A flaw in a widely used template library could let attackers take over certain servers if those applications render attacker-controlled data in an unsafe way.

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

What it actually does

Handlebars versions 4.0.0 through 4.7.8 can mishandle dynamic partial resolution when a crafted non-primitive object is supplied through the template context. If that object can be returned by a dynamic partial lookup, it can bypass conditional checks in resolvePartial(), cause invokePartial() to treat the unresolved partial as compileable input, and pass an attacker-controlled Handlebars AST into env.compile(). In applications using the full Handlebars build with runtime compilation enabled, this can lead to server-side JavaScript execution and, in the worst case, arbitrary command execution in the privileges of the affected application process.

Why it matters to the business

Successful exploitation can allow an unauthenticated remote attacker to execute code on an application server if the application renders attacker-controlled data through vulnerable dynamic partial behavior. The practical risk depends heavily on application design because exploitation requires control over a value used in a dynamic partial lookup, but the impact is high where reachable: service compromise, data theft, credential exposure, lateral movement from the application host, and application downtime. The issue is not currently listed in CISA KEV, is not marked as ransomware-associated, has low EPSS at 0.00703, and has no indicated public exploit maturity, but affected Handlebars versions are common in JavaScript dependency trees, so organizations should still prioritize inventory and upgrade work.

How an attack unfolds

An attacker first identifies an application path that renders Handlebars templates using the full Handlebars package rather than the runtime-only build. The attacker then looks for a template that performs a dynamic partial lookup, such as a partial selected from context data, and finds an input field, request body, API value, stored profile field, CMS content value, or other data path that can influence the rendered context. The attacker supplies a specially structured object instead of ordinary primitive data. When the application renders the template, the crafted object is returned by the dynamic partial lookup and bypasses the expected guard logic in partial resolution. The runtime fails to resolve the partial normally, falls back to compilation, and passes the attacker-controlled AST-like object to env.compile(). The generated JavaScript can then execute under the server-side Node.js process, potentially allowing command execution, file access, environment variable theft, or further compromise depending on process privileges and sandboxing.

How to fix it

Upgrade Handlebars to version 4.7.9 or later wherever the package is used directly or transitively. If an immediate upgrade is not possible, use the runtime-only build, require('handlebars/runtime'), so the vulnerable fallback compilation path is unavailable. Disable or remove dynamic partial lookups when the rendered context includes user-controlled data. Sanitize all context data before rendering and reject non-primitive objects in fields that can influence partial selection. Ensure dependency lockfiles are regenerated and deployed so production systems actually consume the fixed package. Where Handlebars is bundled into frameworks, build tools, plugins, or downstream packages, update the dependent component that embeds or pins Handlebars rather than only changing the top-level dependency declaration.

How to confirm the fix worked

Confirm that dependency manifests and lockfiles no longer resolve handlebars to versions 4.0.0 through 4.7.8. Validate with package managers and software composition analysis tooling, for example npm ls handlebars, yarn why handlebars, pnpm why handlebars, or equivalent SBOM scans. Inspect application code and templates for dynamic partial lookup patterns and verify that any remaining use cannot be influenced by untrusted context data. Confirm that server-side code imports the fixed full package or the runtime-only build where compilation is not required. Run regression tests for template rendering and partial resolution after the upgrade. For high-risk applications, add a negative security test that attempts to pass non-primitive objects into partial-selection context fields and verifies they are rejected or rendered harmlessly.

Typical attack path

  1. Identify a Node.js or JavaScript server-side application using Handlebars 4.0.0 through 4.7.8.
  2. Find routes, API endpoints, stored-content workflows, or template-rendering features where user-controlled data is included in the Handlebars render context.
  3. Determine whether templates use dynamic partial lookup behavior, especially patterns similar to {{> (lookup ...)}} or other context-driven partial names.
  4. Submit a crafted non-primitive object through a controllable data path so it can be returned during dynamic partial resolution.
  5. Trigger server-side template rendering so the vulnerable resolvePartial() and invokePartial() flow is reached.
  6. Cause the unresolved partial fallback path to pass the crafted object to env.compile().
  7. Execute attacker-controlled JavaScript in the application process, then use that access to read secrets, modify data, run system commands, or pivot further.

How to detect it

There are no universal, reliable indicators of compromise for this issue because exploitation occurs inside application-specific Handlebars rendering paths and the attacker-controlled object may not be logged verbatim. To assess possible prior exploitation, review web, API gateway, WAF, and application logs for requests that submitted unusual nested JSON objects, unexpected object-valued fields where strings are normally expected, or payloads that preceded template-rendering failures. Correlate those events with Node.js process telemetry, EDR data, auditd, Sysmon, container runtime logs, and cloud workload logs for unexpected child processes launched by the application process, such as shells, curl/wget, scripting runtimes, or system utilities. Review application error logs for Handlebars partial-resolution or compilation errors around suspicious requests. Inspect deployments for evidence of runtime template compilation, dynamic partial usage, and vulnerable package versions to determine whether the vulnerable path was reachable. Also investigate outbound network connections, new or modified files, environment variable access, credential use anomalies, and lateral movement activity from affected application hosts after suspicious rendering events.

What your security team should do

  • Inventory all applications, build pipelines, server-side rendering services, CMS integrations, email-template systems, and internal tools that use Handlebars.
  • Prioritize internet-facing and multi-tenant services that accept user-controlled JSON, profile data, content blocks, template variables, or API payloads rendered through Handlebars.
  • Upgrade all affected Handlebars installations to 4.7.9 or later and verify lockfile resolution, container images, and deployed artifacts.
  • Search templates for dynamic partial lookup patterns such as {{> (lookup ...)}} and review whether any lookup values can be controlled by users or external systems.
  • Where upgrade timing is constrained, switch to require('handlebars/runtime') and disable runtime compilation for untrusted templates.
  • Add input validation that prevents non-primitive objects from being used in fields that select partials or influence template structure.
  • Review application logs and endpoint telemetry for suspicious template-rendering errors, unexpected child process execution, and unusual outbound network activity from Node.js application processes.
  • Because there is no current KEV listing, ransomware association, named threat actor activity, or known mature public exploit signal, treat this as a high-impact targeted-risk issue rather than confirmed broad exploitation, while still remediating promptly due to potential server-side code execution.

The record

Handlebars provides the power necessary to let users build semantic templates. In versions 4.0.0 through 4.7.8, a crafted object placed in the template context can bypass all conditional guards in `resolvePartial()` and cause `invokePartial()` to return `undefined`. The Handlebars runtime then treats the unresolved partial as a source that needs to be compiled, passing the crafted object to `env.compile()`. Because the object is a valid Handlebars AST containing injected code, the generated JavaScript executes arbitrary commands on the server. The attack requires the adversary to control a value that can be returned by a dynamic partial lookup. Version 4.7.9 fixes the issue. Some workarounds are available. First, use the runtime-only build (`require('handlebars/runtime')`). Without `compile()`, the fallback compilation path in `invokePartial` is unreachable. Second, sanitize context data before rendering: Ensure no value in the context is a non-primitive object that could be passed to a dynamic partial. Third, avoid dynamic partial lookups (`{{> (lookup ...)}}`) when context data is user-controlled.

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