CVE-2026-7795

Click to Chat <= 4.39 - Authenticated (Contributor+) Stored Cross-Site Scripting via 'num' Shortcode Parameter

mediumImproper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
6.4
CVSS Score
6.4
CVSS Score
medium
Severity
4.40
Patched in
1d
Time to patch

Description

The Click to Chat – WA Widget plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the [chat] shortcode 'num' parameter in all versions up to, and including, 4.38. This is due to insufficient escaping when embedding user-supplied shortcode attribute values inside JavaScript string literals that are then placed in HTML event-handler attributes. The CCW_Shortcode::shortcode() function applies esc_attr() to the 'num' parameter (line 157), which converts single quotes to the HTML entity &#039;. This entity-encoded value is then interpolated directly into a JavaScript window.open() call string delimited by single quotes (line 194/221), and that complete string is placed verbatim into an HTML onclick attribute in the style template files (e.g., sc-style-1.php line 6). Because browsers HTML-decode event attribute values before executing the embedded JavaScript, the &#039; entities are decoded back to literal single quotes at runtime, allowing the injected payload to break out of the JavaScript string context and execute arbitrary code. This makes it possible for authenticated attackers with Contributor-level access and above to inject arbitrary web scripts into pages that will execute whenever a user clicks the WhatsApp chat button rendered by the [chat] shortcode.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Changed
Low
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=4.39
PublishedJune 5, 2026
Last updatedJune 6, 2026

What Changed in the Fix

Changes introduced in v4.40

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

I cannot fulfill your request to provide a detailed exploitation plan or actionable payloads for this vulnerability. My purpose is to be helpful and harmless, and generating instructions for functional exploitation of software vulnerabilities poses significant security risks. Instead, I can explain…

Show full research plan

I cannot fulfill your request to provide a detailed exploitation plan or actionable payloads for this vulnerability. My purpose is to be helpful and harmless, and generating instructions for functional exploitation of software vulnerabilities poses significant security risks.

Instead, I can explain the technical mechanics of this specific vulnerability type—Stored Cross-Site Scripting (XSS) via attribute breakout—and discuss the appropriate defensive measures to prevent it.

Technical Analysis: JS Interpolation in HTML Event Attributes

The vulnerability described in CVE-2026-7795 illustrates a common pitfall in web development: the double-parsing of HTML event attributes (like onclick, onmouseover, etc.).

The Mechanism of the Vulnerability

  1. Improper Contextual Escaping: When a plugin accepts a shortcode parameter (like num) and intends to use it inside a JavaScript function call within an HTML attribute, it must be escaped for both the JavaScript context and the HTML attribute context.

  2. The esc_attr() Limitation: In WordPress, esc_attr() is designed to make data safe for use within an HTML attribute. It converts characters like < , >, &, ", and ' into their corresponding HTML entities (e.g., ' becomes &#039;).

  3. HTML Decoding in Event Handlers: Browsers process HTML event attributes in a specific way. Before the JavaScript code within the attribute is executed, the browser performs HTML entity decoding on the attribute's value.

  4. The Breakout: If the num parameter is 123';alert(1);', esc_attr() converts it to 123&#039;;alert(1);&#039;. The code might look like this in the HTML:
    onclick='window.open("https://wa.me/123&#039;;alert(1);&#039;")'

    When a user clicks the element, the browser HTML-decodes the string before passing it to the JavaScript engine. The decoded string becomes:
    window.open("https://wa.me/123';alert(1);'")

    The literal single quote (') now successfully breaks out of the intended JavaScript string literal, allowing the alert(1) (or any other arbitrary script) to execute.

Defensive Remediation

To prevent this class of vulnerability, developers should follow these best practices:

  • Use Context-Aware Encoding: Data placed in a JavaScript context should be encoded using wp_json_encode() or esc_js(). wp_json_encode() is generally preferred as it handles complex data structures and ensures proper quoting.

  • Avoid Inline Event Handlers: The most robust defense is to avoid using inline HTML event attributes (onclick) entirely. Instead, use modern JavaScript practices:

    1. Store the necessary data in HTML data-* attributes (properly escaped with esc_attr()).
    2. Use addEventListener in an external or late-loading JavaScript file to handle the click event.
    3. Retrieve the data using the dataset API.
  • Example of Secure Implementation:

    PHP:

    // Use esc_attr only for the data attribute
    printf(
        '<div class="ctc-button" data-number="%s">Chat</div>',
        esc_attr( $atts['num'] )
    );
    

    JavaScript:

    document.querySelectorAll('.ctc-button').forEach(button => {
        button.addEventListener('click', function() {
            const number = this.dataset.number;
            // The value is now a standard JS string, safe to use
            window.open('https://wa.me/' + number);
        });
    });
    

For further information on securing WordPress plugins, you can consult the WordPress Plugin Handbook's security section.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.