VYPR
High severityNVD Advisory· Published Feb 27, 2026· Updated Feb 27, 2026

CVE-2026-26861

CVE-2026-26861

Description

CleverTap Web SDK version 1.15.2 and earlier is vulnerable to Cross-Site Scripting (XSS) via window.postMessage. The handleCustomHtmlPreviewPostMessageEvent function in src/util/campaignRender/nativeDisplay.js performs insufficient origin validation using the includes() method, which can be bypassed by an attacker using a subdomain

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

CleverTap Web SDK <=1.15.2 is vulnerable to XSS via postMessage due to insufficient origin validation using includes(), allowing subdomain-based bypass.

Vulnerability

Description

CleverTap Web SDK versions 1.15.2 and earlier are vulnerable to Cross-Site Scripting (XSS) via window.postMessage. The handleCustomHtmlPreviewPostMessageEvent function in src/util/campaignRender/nativeDisplay.js performs origin validation using the includes() method on the event origin, which can be bypassed by an attacker using a subdomain of an allowed origin [1][2].

Exploitation

An attacker can send a crafted postMessage from a subdomain of a trusted origin (e.g., attacker.clevertap.com) to the vulnerable SDK running in a victim's browser. The SDK incorrectly accepts the message because includes() matches the subdomain as a substring, allowing the attacker to inject arbitrary HTML or JavaScript into the page context [3][4].

Impact

Successful exploitation leads to reflected Cross-Site Scripting (XSS), enabling the attacker to execute arbitrary JavaScript in the context of the victim's session. This could result in data theft, session hijacking, or other malicious actions within the application that embeds the CleverTap SDK [1][2].

Mitigation

The vulnerability is fixed in the commit 84695b726a751614ddc3a4f71382c239c5833e03 by replacing includes() with endsWith() for strict origin validation. Users should update to a version later than 1.15.2 [3][4].

AI Insight generated on May 18, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
clevertap-web-sdknpm
< 1.15.31.15.3

Affected products

2

Patches

1
84695b726a75

[WEB-3755] Strict Domain Check

https://github.com/CleverTap/clevertap-web-sdkKunal SInghMay 28, 2025via ghsa
6 files changed · +17 11
  • clevertap.js+7 4 modified
    @@ -11643,11 +11643,10 @@
     
       const handleMessageEvent = event => {
         if (event.data && isValidUrl(event.data.originUrl)) {
    -      const msgOrigin = new URL(event.data.originUrl).origin; // Visual Editor is opened from only dashboard, while preview can be opened from both dashboard & Visual Editor
    +      // Visual Editor is opened from only dashboard, while preview can be opened from both dashboard & Visual Editor
           // therefore adding check for self origin
           // Visual Editor can only be opened in their domain not inside dashboard
    -
    -      if (!event.origin.includes(WVE_URL_ORIGIN.CLEVERTAP) && !event.origin.includes(window.location.origin) || event.origin !== msgOrigin) {
    +      if (!event.origin.endsWith(WVE_URL_ORIGIN.CLEVERTAP) && !event.origin.endsWith(window.location.origin)) {
             return;
           }
         } else {
    @@ -12488,7 +12487,7 @@
       };
     
       function handleCustomHtmlPreviewPostMessageEvent(event, logger) {
    -    if (!event.origin.includes(WVE_URL_ORIGIN.CLEVERTAP)) {
    +    if (!event.origin.endsWith(WVE_URL_ORIGIN.CLEVERTAP)) {
           return;
         }
     
    @@ -13328,6 +13327,10 @@
           httpsIframe.setAttribute('src', httpsIframePath);
           document.body.appendChild(httpsIframe);
           window.addEventListener('message', event => {
    +        if (!event.origin.endsWith(WVE_URL_ORIGIN.CLEVERTAP)) {
    +          return;
    +        }
    +
             if (event.data != null) {
               let obj = {};
     
    
  • clevertap.js.map+1 1 modified
  • clevertap.min.js+1 1 modified
  • src/modules/notification.js+4 0 modified
    @@ -17,6 +17,7 @@ import {
     import { setNotificationHandlerValues, processSoftPrompt } from './webPushPrompt/prompt'
     
     import { isChrome, isFirefox, isSafari } from '../util/helpers'
    +import { WVE_URL_ORIGIN } from './visualBuilder/builder_constants'
     
     export default class NotificationHandler extends Array {
       #oldValues
    @@ -517,6 +518,9 @@ export default class NotificationHandler extends Array {
           httpsIframe.setAttribute('src', httpsIframePath)
           document.body.appendChild(httpsIframe)
           window.addEventListener('message', (event) => {
    +        if (!event.origin.endsWith(WVE_URL_ORIGIN.CLEVERTAP)) {
    +          return
    +        }
             if (event.data != null) {
               let obj = {}
               try {
    
  • src/modules/visualBuilder/pageBuilder.js+3 4 modified
    @@ -49,14 +49,13 @@ export const handleActionMode = (_logger, accountId) => {
     
     const handleMessageEvent = (event) => {
       if (event.data && isValidUrl(event.data.originUrl)) {
    -    const msgOrigin = new URL(event.data.originUrl).origin
         // Visual Editor is opened from only dashboard, while preview can be opened from both dashboard & Visual Editor
         // therefore adding check for self origin
         // Visual Editor can only be opened in their domain not inside dashboard
    +
         if (
    -      (!event.origin.includes(WVE_URL_ORIGIN.CLEVERTAP) &&
    -      !event.origin.includes(window.location.origin)) ||
    -      event.origin !== msgOrigin
    +      !event.origin.endsWith(WVE_URL_ORIGIN.CLEVERTAP) &&
    +      !event.origin.endsWith(window.location.origin)
         ) {
           return
         }
    
  • src/util/campaignRender/nativeDisplay.js+1 1 modified
    @@ -116,7 +116,7 @@ export const handleJson = (targetingMsgJson) => {
     }
     
     function handleCustomHtmlPreviewPostMessageEvent (event, logger) {
    -  if (!event.origin.includes(WVE_URL_ORIGIN.CLEVERTAP)) {
    +  if (!event.origin.endsWith(WVE_URL_ORIGIN.CLEVERTAP)) {
         return
       }
       const eventData = JSON.parse(event.data)
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

6

News mentions

0

No linked articles in our index yet.