CVE-2026-5776

Email Encoder – Protect Email Addresses and Phone Numbers < 2.4.7 - 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
2.4.7
Patched in
5d
Time to patch

Description

The Email Encoder – Protect Email Addresses and Phone Numbers plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to 2.4.7 due to insufficient input sanitization and output escaping. This makes it possible for unauthenticated attackers 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<2.4.7
PublishedJune 11, 2026
Last updatedJune 15, 2026
Affected pluginemail-encoder-bundle

What Changed in the Fix

Changes introduced in v2.4.7

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

I cannot fulfill your request to create a detailed exploitation plan for CVE-2026-5776. My purpose is to be helpful and harmless, and providing actionable instructions for exploiting vulnerabilities in specific software versions is against my safety policy. However, I can provide a general overview…

Show full research plan

I cannot fulfill your request to create a detailed exploitation plan for CVE-2026-5776. My purpose is to be helpful and harmless, and providing actionable instructions for exploiting vulnerabilities in specific software versions is against my safety policy.

However, I can provide a general overview of the security principles involved and how developers can prevent similar vulnerabilities like Stored Cross-Site Scripting (XSS) in WordPress plugins.

Understanding the Security Concepts

Stored Cross-Site Scripting (XSS)
Stored XSS occurs when a web application receives data from a user and stores it in its database without sufficient sanitization. This data is later rendered on a page for other users (often administrators or visitors) without proper escaping. If the stored data contains malicious JavaScript, that script will execute in the context of the user's browser who views the page.

In the context of WordPress plugins, this often happens when:

  1. Unsanitized Input: Data from $_POST, $_GET, or shortcode attributes is saved directly via update_option(), update_post_meta(), or custom database queries.
  2. Unescaped Output: The saved data is retrieved and echoed to the page without using WordPress's context-aware escaping functions.

Defensive Best Practices in WordPress

To prevent Stored XSS, developers should follow the principle of "Sanitize on Input, Escape on Output."

1. Input Sanitization

Always sanitize data before it reaches the database. Use functions that strip or encode dangerous characters:

  • sanitize_text_field(): Strips tags, line breaks, and extra whitespace.
  • sanitize_email(): Strips all characters not allowed in an email.
  • absint(): Ensures a value is a non-negative integer.
  • wp_kses(): Allows only specific HTML tags and attributes.

2. Output Escaping

Always escape data just before it is rendered in the HTML. This ensures the browser treats the data as literal text rather than executable code:

  • esc_html(): Use when outputting data inside an HTML element (e.g., <div><?php echo esc_html( $data ); ?></div>).
  • esc_attr(): Use when outputting data inside an HTML attribute (e.g., <input value="<?php echo esc_attr( $data ); ?>">).
  • esc_url(): Use for URLs in href or src attributes.
  • wp_json_encode(): Use when passing PHP data to JavaScript variables.

3. Nonce Verification

WordPress nonces provide protection against Cross-Site Request Forgery (CSRF). While they aren't a direct defense against XSS, they ensure that an action (like saving a setting) was intentionally initiated by an authorized user.

  • Generate nonces using wp_create_nonce( 'action_name' ).
  • Verify them using check_admin_referer() or wp_verify_nonce().

Researching the Vulnerability

If you are interested in the technical details of how CVE-2026-5776 was addressed, I recommend reviewing the plugin's changelog and comparing the source code of version 2.4.6 with the patched version 2.4.7. Security researchers typically look for where sanitization was added to input handlers or where escaping was added to the functions responsible for rendering the encoded content (such as the encode_ascii or encode_escape methods in the Encoding class).

For more information on secure WordPress development, you can consult the official WordPress Plugin Handbook on Security.

Research Findings
Static analysis — not yet PoC-verified

Summary

The Email Encoder plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the `data-enc-email` attribute in versions up to 2.4.7. This occurs because the plugin fails to escape the output of encoded email addresses when inserting them into HTML attributes, allowing attackers to break out of the attribute and inject malicious scripts.

Vulnerable Code

/* src/Validate/Encoding.php:154 */
// add data-enc-email after "<input"
$inputWithDataAttr = substr( $input, 0, 6 );
$inputWithDataAttr .= ' data-enc-email="' . $this->get_encoded_email( $email ) . '"';
$inputWithDataAttr .= substr( $input, 6 );

---

/* src/Validate/Encoding.php:248 (in create_protected_mailto method) */
// set attrs
$link .= 'href="javascript:;" ';
$link .= 'data-enc-email="' . $encoded_email . '" ';

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/email-encoder-bundle/2.4.6/src/Validate/Encoding.php /home/deploy/wp-safety.org/data/plugin-versions/email-encoder-bundle/2.4.7/src/Validate/Encoding.php
--- /home/deploy/wp-safety.org/data/plugin-versions/email-encoder-bundle/2.4.6/src/Validate/Encoding.php	2026-03-30 04:03:26.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/email-encoder-bundle/2.4.7/src/Validate/Encoding.php	2026-04-22 02:07:48.000000000 +0000
@@ -154,7 +154,7 @@
 
         // add data-enc-email after "<input"
         $inputWithDataAttr = substr( $input, 0, 6 );
-        $inputWithDataAttr .= ' data-enc-email="' . $this->get_encoded_email( $email ) . '"';
+        $inputWithDataAttr .= ' data-enc-email="' . esc_attr( $this->get_encoded_email( $email ) ) . '"';
         $inputWithDataAttr .= substr( $input, 6 );
 
         // mark link as successfullly encoded (for admin users)
@@ -248,7 +248,7 @@
 
                     // set attrs
                     $link .= 'href="javascript:;" ';
-                    $link .= 'data-enc-email="' . $encoded_email . '" ';
+                    $link .= 'data-enc-email="' . esc_attr( $encoded_email ) . '" ';
                 }
 
             } else {

Exploit Outline

An unauthenticated attacker can exploit this vulnerability by submitting content containing a specially crafted email address that, when processed by the plugin's encoding logic, results in a payload that breaks out of an HTML attribute. Since the plugin applies ROT13 and replaces '@' with '[at]', the attacker must account for these transformations (e.g., using a double quote '"' which remains '"' in ROT13). If the plugin is configured to automatically encode all emails on the site or via shortcodes like [eeb_mailto], an attacker can inject a payload like `test" onmouseover="alert(1)` into any field that the plugin parses. When a user or administrator views the page, the injected event handler will execute in their browser context.

Check if your site is affected.

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