Every CVESearch/Get API key

GHSA-26wg-9xf2-q495

Novu has a XSS sanitization bypass

8.1 HighFix available

Summary

XSS sanitization is incomplete, some attributes are missing such as oncontentvisibilityautostatechange=. This allows for the email preview to render HTML that executes arbitrary JavaScript,

Details

Sanitization is implemented here: https://github.com/novuhq/novu/blob/next/libs/application-generic/src/services/sanitize/sanitizer.service.ts

With allowedAttributes: false, all attributes are allowed through sanitize-html. Even dangerous ones like oncontentvisibilityautostatechange=. The DANGEROUS_ATTRIBUTES array tries to handle this by denying more attributes after the fact, but this list is incomplete. I copied all well-known payloads from: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet And found that the oncontentvisibilityautostatechange= attribute isn't detected.

PS. there seems to also be another even more lax sanitizer here, but I wasn't able to figure out where it is used: https://github.com/novuhq/novu/blob/next/packages/framework/src/utils/sanitize.utils.ts

PoC

  1. Create a new workflow and add an Email step
  2. In the body, write the following HTML code:
<a oncontentvisibilityautostatechange="alert(window.origin)" style="display:block;content-visibility:auto">
  1. Wait a second and notice the XSS popup showing the current origin:

<img width="1515" height="610" alt="image" src="https://github.com/user-attachments/assets/7d519a50-3bed-4f04-b78c-9c5938717433" />

https://dashboard.novu.co/env/dev_env_gVtdgDEhgf1CetwX/workflows/onboarding-demo-workflow_wf_gVtdh2uV0h7j3ffK/steps/email-step_st_gVtqdgIrOkYVvP9F/editor

Impact

This may look like a Self-XSS similar to https://github.com/novuhq/novu/security/advisories/GHSA-w8vm-jx29-52fr, but it can be more impactful. First of all, if multiple users can access this dashboard, the link above can directly bring the to the email step editor to trigger the XSS. An attacker can also use the Google/GitHub OAuth flows without completing the code callback step, and send that URL to the victim to intentionally log the vicitm into the attacker's account. If the attacker has prepared an XSS payload there, they will now be allowed to view it, so it triggers.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
None
User interaction
Required

What an attacker can affect

Confidentiality
High
Integrity
High
Availability
None

What each source reports

GitHub Advisories Score used8.1

Novu has a XSS sanitization bypass

Summary

XSS sanitization is incomplete, some attributes are missing such as oncontentvisibilityautostatechange=. This allows for the email preview to render HTML that executes arbitrary JavaScript,

Details

Sanitization is implemented here: https://github.com/novuhq/novu/blob/next/libs/application-generic/src/services/sanitize/sanitizer.service.ts

With allowedAttributes: false, all attributes are allowed through sanitize-html. Even dangerous ones like oncontentvisibilityautostatechange=. The DANGEROUS_ATTRIBUTES array tries to handle this by denying more attributes after the fact, but this list is incomplete. I copied all well-known payloads from: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet And found that the oncontentvisibilityautostatechange= attribute isn't detected.

PS. there seems to also be another even more lax sanitizer here, but I wasn't able to figure out where it is used: https://github.com/novuhq/novu/blob/next/packages/framework/src/utils/sanitize.utils.ts

PoC

  1. Create a new workflow and add an Email step
  2. In the body, write the following HTML code:
<a oncontentvisibilityautostatechange="alert(window.origin)" style="display:block;content-visibility:auto">
  1. Wait a second and notice the XSS popup showing the current origin:

<img width="1515" height="610" alt="image" src="https://github.com/user-attachments/assets/7d519a50-3bed-4f04-b78c-9c5938717433" />

https://dashboard.novu.co/env/dev_env_gVtdgDEhgf1CetwX/workflows/onboarding-demo-workflow_wf_gVtdh2uV0h7j3ffK/steps/email-step_st_gVtqdgIrOkYVvP9F/editor

Impact

This may look like a Self-XSS similar to https://github.com/novuhq/novu/security/advisories/GHSA-w8vm-jx29-52fr, but it can be more impactful. First of all, if multiple users can access this dashboard, the link above can directly bring the to the email step editor to trigger the XSS. An attacker can also use the Google/GitHub OAuth flows without completing the code callback step, and send that URL to the victim to intentionally log the vicitm into the attacker's account. If the attacker has prepared an XSS payload there, they will now be allowed to view it, so it triggers.

Record
GHSA-26wg-9xf2-q495
CVSS 3.1
8.1 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N
Weakness
CWE-79
Updated
2026-11-02
OSV8.1

Novu has a XSS sanitization bypass

Summary

XSS sanitization is incomplete, some attributes are missing such as oncontentvisibilityautostatechange=. This allows for the email preview to render HTML that executes arbitrary JavaScript,

Details

Sanitization is implemented here: https://github.com/novuhq/novu/blob/next/libs/application-generic/src/services/sanitize/sanitizer.service.ts

With allowedAttributes: false, all attributes are allowed through sanitize-html. Even dangerous ones like oncontentvisibilityautostatechange=. The DANGEROUS_ATTRIBUTES array tries to handle this by denying more attributes after the fact, but this list is incomplete. I copied all well-known payloads from: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet And found that the oncontentvisibilityautostatechange= attribute isn't detected.

PS. there seems to also be another even more lax sanitizer here, but I wasn't able to figure out where it is used: https://github.com/novuhq/novu/blob/next/packages/framework/src/utils/sanitize.utils.ts

PoC

  1. Create a new workflow and add an Email step
  2. In the body, write the following HTML code:
<a oncontentvisibilityautostatechange="alert(window.origin)" style="display:block;content-visibility:auto">
  1. Wait a second and notice the XSS popup showing the current origin:

<img width="1515" height="610" alt="image" src="https://github.com/user-attachments/assets/7d519a50-3bed-4f04-b78c-9c5938717433" />

https://dashboard.novu.co/env/dev_env_gVtdgDEhgf1CetwX/workflows/onboarding-demo-workflow_wf_gVtdh2uV0h7j3ffK/steps/email-step_st_gVtqdgIrOkYVvP9F/editor

Impact

This may look like a Self-XSS similar to https://github.com/novuhq/novu/security/advisories/GHSA-w8vm-jx29-52fr, but it can be more impactful. First of all, if multiple users can access this dashboard, the link above can directly bring the to the email step editor to trigger the XSS. An attacker can also use the Google/GitHub OAuth flows without completing the code callback step, and send that URL to the victim to intentionally log the vicitm into the attacker's account. If the attacker has prepared an XSS payload there, they will now be allowed to view it, so it triggers.

Record
GHSA-26wg-9xf2-q495
CVSS 3.1
8.1 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N
Weakness
CWE-79
Updated
2026-11-02

Affected packages

Affected packages
PackageAffectedFixed
novu/api
npm
before 3.15.0
3.15.0

History

History
RecordedChangedSources
first indexedGitHub Advisories, OSV

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

In short

GHSA-26wg-9xf2-q495 is a high vulnerability (CVSS 8.1) in novu/api, published April 14, 2026. No source lists public exploit code. Fixed in novu/api 3.15.0.

References

MoveEnter Open