Every CVE Search/ Get API key

CVE-2026-63466

Unleash: Global Mustache.escape override disables HTML escaping process-wide, enabling Slack/Teams link-injection via unrestricted username

4.1 MediumFix available

Unleash is an open-source feature management platform. Prior to 8.0.3, FeatureEventFormatterMd.format in src/lib/addons/feature-event-formatter-md.ts assigns Mustache.escape to an identity function before rendering action and path templates. Because Mustache.escape is process-wide, the assignment disables escaping for subsequent Mustache.render calls in email-service.ts, webhook.ts, datadog.ts, and new-relic.ts. An editor-level user can place Slack or Microsoft Teams link syntax in an unrestricted username, trigger a feature event, and inject an attacker-labeled link into a trusted outbound notification channel, while other Mustache sinks remain unescaped until restart. This issue is fixed in version 8.0.3.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
Low
User interaction
Required

What an attacker can affect

Confidentiality
None
Integrity
Low
Availability
None

Exploit likelihood

0.32%Up 0.1 points since Aug 22, 2026
90%50%10%1%

What each source reports

CVE List Score used 4.1

Unleash: Global Mustache.escape override disables HTML escaping process-wide, enabling Slack/Teams link-injection via unrestricted username

Unleash is an open-source feature management platform. Prior to 8.0.3, FeatureEventFormatterMd.format in src/lib/addons/feature-event-formatter-md.ts assigns Mustache.escape to an identity function before rendering action and path templates. Because Mustache.escape is process-wide, the assignment disables escaping for subsequent Mustache.render calls in email-service.ts, webhook.ts, datadog.ts, and new-relic.ts. An editor-level user can place Slack or Microsoft Teams link syntax in an unrestricted username, trigger a feature event, and inject an attacker-labeled link into a trusted outbound notification channel, while other Mustache sinks remain unescaped until restart. This issue is fixed in version 8.0.3.

Record
CVE-2026-63466
CVSS 3.1
4.1 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:N/I:L/A:N
Weakness
CWE-116
Updated
2026-11-02
EUVDEUVD-2026-64042 4.1

Unleash is an open-source feature management platform. Prior to 8.0.3, FeatureEventFormatterMd.format in src/lib/addons/feature-event-formatter-md.ts assigns Mustache.escape to an identity function before rendering action and path templates. Because Mustache.escape is process-wide, the assignment disables escaping for subsequent Mustache.render calls in email-service.ts, webhook.ts, datadog.ts, and new-relic.ts. An editor-level user can place Slack or Microsoft Teams link syntax in an unrestricted username, trigger a feature event, and inject an attacker-labeled link into a trusted outbound notification channel, while other Mustache sinks remain unescaped until restart. This issue is fixed in version 8.0.3.

Record
EUVD-2026-64042
CVSS 3.1
4.1 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:N/I:L/A:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-w4mq-xh27-6xpx 4.1

Unleash: Global Mustache.escape override disables HTML escaping process-wide, enabling Slack/Teams link-injection via unrestricted username

Vulnerability Details

File: src/lib/addons/feature-event-formatter-md.ts Line: 355 (in v8.0.1; format() method)

Root Cause

FeatureEventFormatterMd.format() does:

Mustache.escape = (text) => text;
const text = Mustache.render(action, context);

mustache (pinned ^4.2.0, confirmed installed 4.2.0) keeps escape as a module-level singleton (mustache.js: mustache.escape = escapeHtml;), read by every Mustache.render() call in the process unless a per-call config.escape override is passed (var escape = this.getConfigEscape(config) || mustache.escape;). Node's module cache guarantees every import Mustache from 'mustache' in the process — feature-event-formatter-md.ts, email-service.ts, webhook.ts, datadog.ts, new-relic.ts — shares the same object instance.

This assignment therefore permanently disables HTML escaping for every other Mustache.render() call in the same Node process (including email-service.ts templates) from the moment any single notification addon (Webhook, Slack legacy, Microsoft Teams, Datadog, New Relic) first formats any event, for the remaining lifetime of the process.

feature-event-formatter-md-events.ts (EVENT_MAP) confirms the blast radius: nearly every event's action template interpolates attacker-controlled values with single-mustache (intended-to-be-escaped) syntax, most importantly {{user}}, which is event.createdBy — the acting account's username (or email if set; src/lib/util/extract-user.ts: extractUsernameFromUser). Neither username nor name have any charset/length validation anywhere in the codebase (create-user-schema.ts, create-invited-user-schema.ts, user-service.ts:289 only does Joi.assert(name, Joi.string(), 'Name') — a type check, nothing more).

Slack's own API docs require &, <, > to be replaced with &amp;, &lt;, &gt; before sending user-generated text, specifically so Slack's mrkdwn parser does not interpret it as <url|label> link syntax. Mustache's default escapeHtml happens to produce exactly those entities, so this was (likely unintentionally) the application's only defense against link-injection in chat notifications — and it is unconditionally switched off by the same code path that depends on it.

Attack Scenario

  1. Admin has a Webhook, Slack (legacy), Microsoft Teams, Datadog, or New Relic integration configured (a very common production setup for flag-change notifications).
  2. Attacker has (or self-registers, if public signup is enabled — POST /invite/:token/signup is permission: NONE) any Editor-level account and sets username to e.g. evil<https://attacker.example/urgent-rollback|Click here to view incident>.
  3. Attacker performs any ordinary write action (create/update/toggle a feature flag — routine, no special privilege beyond Editor on one project).
  4. The configured addon's handleEvent() calls this.msgFormatter.format(event), which mutates the global escape function and immediately renders the {{user}}-containing template with escaping disabled.
  5. The resulting message — containing the attacker's raw <url|label> Slack link syntax — is POSTed to the team's Slack/Teams channel or webhook endpoint and rendered as a real, clickable, attacker-labeled hyperlink inside a trusted automated notification feed.

Vulnerable Code

Mustache.escape = (text) => text;

const text = Mustache.render(action, context);
const url = path
    ? `${this.unleashUrl}${Mustache.render(path, context)}`
    : undefined;

Impact

  • Stored markdown/link-injection (phishing-link injection) into any configured outbound notification channel (Slack legacy, MS Teams, Webhook default markdown, Datadog, New Relic), using an attacker-controlled username — no admin privilege required, only Editor on a single project, and potentially reachable through public self-signup.
  • Secondary: loss of HTML escaping for any other reachable Mustache…
Record
GHSA-w4mq-xh27-6xpx
CVSS 3.1
4.1 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:N/I:L/A:N
Weakness
CWE-116
Updated
2026-11-02
NVD 4.1

Unleash is an open-source feature management platform. Prior to 8.0.3, FeatureEventFormatterMd.format in src/lib/addons/feature-event-formatter-md.ts assigns Mustache.escape to an identity function before rendering action and path templates. Because Mustache.escape is process-wide, the assignment disables escaping for subsequent Mustache.render calls in email-service.ts, webhook.ts, datadog.ts, and new-relic.ts. An editor-level user can place Slack or Microsoft Teams link syntax in an unrestricted username, trigger a feature event, and inject an attacker-labeled link into a trusted outbound notification channel, while other Mustache sinks remain unescaped until restart. This issue is fixed in version 8.0.3.

Record
CVE-2026-63466
CVSS 3.1
4.1 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:N/I:L/A:N
Weakness
CWE-116
Updated
2026-11-02
OSV 4.1

Unleash: Global Mustache.escape override disables HTML escaping process-wide, enabling Slack/Teams link-injection via unrestricted username

Unleash is an open-source feature management platform. Prior to 8.0.3, FeatureEventFormatterMd.format in src/lib/addons/feature-event-formatter-md.ts assigns Mustache.escape to an identity function before rendering action and path templates. Because Mustache.escape is process-wide, the assignment disables escaping for subsequent Mustache.render calls in email-service.ts, webhook.ts, datadog.ts, and new-relic.ts. An editor-level user can place Slack or Microsoft Teams link syntax in an unrestricted username, trigger a feature event, and inject an attacker-labeled link into a trusted outbound notification channel, while other Mustache sinks remain unescaped until restart. This issue is fixed in version 8.0.3.

Record
CVE-2026-63466
CVSS 3.1
4.1 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:N/I:L/A:N
Weakness
CWE-116
Updated
2026-11-02
OSVGHSA-w4mq-xh27-6xpx 4.1

Unleash: Global Mustache.escape override disables HTML escaping process-wide, enabling Slack/Teams link-injection via unrestricted username

Vulnerability Details

File: src/lib/addons/feature-event-formatter-md.ts Line: 355 (in v8.0.1; format() method)

Root Cause

FeatureEventFormatterMd.format() does:

Mustache.escape = (text) => text;
const text = Mustache.render(action, context);

mustache (pinned ^4.2.0, confirmed installed 4.2.0) keeps escape as a module-level singleton (mustache.js: mustache.escape = escapeHtml;), read by every Mustache.render() call in the process unless a per-call config.escape override is passed (var escape = this.getConfigEscape(config) || mustache.escape;). Node's module cache guarantees every import Mustache from 'mustache' in the process — feature-event-formatter-md.ts, email-service.ts, webhook.ts, datadog.ts, new-relic.ts — shares the same object instance.

This assignment therefore permanently disables HTML escaping for every other Mustache.render() call in the same Node process (including email-service.ts templates) from the moment any single notification addon (Webhook, Slack legacy, Microsoft Teams, Datadog, New Relic) first formats any event, for the remaining lifetime of the process.

feature-event-formatter-md-events.ts (EVENT_MAP) confirms the blast radius: nearly every event's action template interpolates attacker-controlled values with single-mustache (intended-to-be-escaped) syntax, most importantly {{user}}, which is event.createdBy — the acting account's username (or email if set; src/lib/util/extract-user.ts: extractUsernameFromUser). Neither username nor name have any charset/length validation anywhere in the codebase (create-user-schema.ts, create-invited-user-schema.ts, user-service.ts:289 only does Joi.assert(name, Joi.string(), 'Name') — a type check, nothing more).

Slack's own API docs require &, <, > to be replaced with &amp;, &lt;, &gt; before sending user-generated text, specifically so Slack's mrkdwn parser does not interpret it as <url|label> link syntax. Mustache's default escapeHtml happens to produce exactly those entities, so this was (likely unintentionally) the application's only defense against link-injection in chat notifications — and it is unconditionally switched off by the same code path that depends on it.

Attack Scenario

  1. Admin has a Webhook, Slack (legacy), Microsoft Teams, Datadog, or New Relic integration configured (a very common production setup for flag-change notifications).
  2. Attacker has (or self-registers, if public signup is enabled — POST /invite/:token/signup is permission: NONE) any Editor-level account and sets username to e.g. evil<https://attacker.example/urgent-rollback|Click here to view incident>.
  3. Attacker performs any ordinary write action (create/update/toggle a feature flag — routine, no special privilege beyond Editor on one project).
  4. The configured addon's handleEvent() calls this.msgFormatter.format(event), which mutates the global escape function and immediately renders the {{user}}-containing template with escaping disabled.
  5. The resulting message — containing the attacker's raw <url|label> Slack link syntax — is POSTed to the team's Slack/Teams channel or webhook endpoint and rendered as a real, clickable, attacker-labeled hyperlink inside a trusted automated notification feed.

Vulnerable Code

Mustache.escape = (text) => text;

const text = Mustache.render(action, context);
const url = path
    ? `${this.unleashUrl}${Mustache.render(path, context)}`
    : undefined;

Impact

  • Stored markdown/link-injection (phishing-link injection) into any configured outbound notification channel (Slack legacy, MS Teams, Webhook default markdown, Datadog, New Relic), using an attacker-controlled username — no admin privilege required, only Editor on a single project, and potentially reachable through public self-signup.
  • Secondary: loss of HTML escaping for any other reachable Mustache…
Record
GHSA-w4mq-xh27-6xpx
CVSS 3.1
4.1 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:N/I:L/A:N
Weakness
CWE-116
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
unleash-server
npm
before 8.0.3
8.0.3

History

History
RecordedChangedSources
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-63466 is a medium vulnerability (CVSS 4.1) in Unleash, published August 21, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.32%, the 25th percentile. Fixed in unleash-server 8.0.3.

References

This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open