CVE-2025-62761

Knowledge Base documentation & wiki plugin – BasePress <= 2.17.0.1 - Authenticated (Contributor+) Stored Cross-Site Scripting

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

Description

The Knowledge Base documentation & wiki plugin – BasePress plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to, and including, 2.17.0.1 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<=2.17.0.1
PublishedDecember 31, 2025
Last updatedJanuary 13, 2026
Affected pluginbasepress
Research Plan
Unverified

This research plan focuses on identifying and exploiting a Stored Cross-Site Scripting (XSS) vulnerability in the **BasePress Docs** plugin (versions <= 2.17.0.1). Since the vulnerability is accessible to **Contributors**, the most likely attack vectors are Knowledge Base article metadata (Post Meta…

Show full research plan

This research plan focuses on identifying and exploiting a Stored Cross-Site Scripting (XSS) vulnerability in the BasePress Docs plugin (versions <= 2.17.0.1). Since the vulnerability is accessible to Contributors, the most likely attack vectors are Knowledge Base article metadata (Post Meta) or Shortcode attributes that are rendered without proper escaping.


1. Vulnerability Summary

  • Vulnerability: Stored Cross-Site Scripting (XSS)
  • Affected Plugin: Knowledge Base documentation & wiki plugin – BasePress Docs
  • Affected Versions: <= 2.17.0.1
  • Required Privilege: Contributor or higher
  • Description: The plugin fails to sanitize user-provided input when saving Knowledge Base article settings or metadata and subsequently fails to escape that data when rendering it on the frontend or in admin pages. This allows a Contributor to inject malicious scripts that execute in the context of other users (including Administrators).

2. Attack Vector Analysis

  • Primary Endpoint: WordPress Post Editor (for knowledgebase post type) or AJAX handlers for saving article settings.
  • Vulnerable Parameter: Likely a custom field (post meta) associated with Knowledge Base articles, such as "Article Icon," "Sidebar Selection," or "Breadcrumb Title."
  • Authentication: Requires a Contributor-level account. Contributors can create and edit their own knowledgebase posts but cannot publish them; however, the XSS is "Stored" upon saving a draft.
  • Preconditions: The BasePress plugin must be active, and at least one Knowledge Base must be configured.

3. Code Flow (Inferred)

  1. Entry Point (Source): A Contributor edits a Knowledge Base article. They provide input into a custom field provided by BasePress (e.g., an icon class name or a custom title).
  2. Processing: The plugin catches the save_post hook or an AJAX action (e.g., wp_ajax_basepress_save_meta).
  3. Storage: The input is saved to the database using update_post_meta() or update_option() without using sanitize_text_field() or wp_kses().
  4. Rendering (Sink): When the article is viewed (frontend) or managed (backend), the plugin retrieves the data using get_post_meta() and echoes it directly without using esc_html(), esc_attr(), or wp_kses().

4. Nonce Acquisition Strategy

If the vulnerability exists in the standard post editor's meta boxes, the _wpnonce for the post edit screen is required. If it exists in an AJAX handler, we must find the localized nonce.

Recommended Extraction Steps:

  1. Identify the Shortcode/Page: Identify a page where BasePress scripts are loaded. Usually, this is any page with the [basepress] shortcode.
  2. Create a Test Page:
    wp post create --post_type=page --post_title="KB Home" --post_status=publish --post_content='[basepress]'
    
  3. Extract Nonce via Browser:
    Navigate to the created page or the Admin KB editor and use browser_eval:
    • Meta Box Nonce: browser_eval("document.querySelector('#basepress_meta_box_nonce')?.value") (inferred ID)
    • AJAX Nonce: browser_eval("window.basepress_admin?.nonce") (inferred variable)

5. Exploitation Strategy

Step 1: Reconnaissance (Grep for Sinks)

Find where the plugin echoes data without escaping. Run these in the plugin directory:

# Find shortcode rendering
grep -rn "add_shortcode" .
# Find unescaped echoes of post meta
grep -rn "echo.*get_post_meta" . | grep -v "esc_"
# Find where post meta is saved
grep -rn "update_post_meta" .

Step 2: Test Payload Injection (via Post Meta)

If a field like _basepress_icon is found to be unescaped:

  1. Identify Post ID: Create a draft knowledgebase article as a Contributor.
  2. Inject Payload:
    Use http_request to simulate saving the post with the payload in the suspected meta field.
    • URL: http://localhost:8080/wp-admin/post.php
    • Method: POST
    • Payload:
      action=editpost&
      post_ID=[POST_ID]&
      basepress_icon="><script>alert(document.domain)</script>&
      _wpnonce=[NONCE]
      

Step 3: Triggering the XSS

View the article on the frontend:

  • URL: http://localhost:8080/?post_type=knowledgebase&p=[POST_ID]
  • Detection: The browser should trigger an alert.

6. Test Data Setup

  1. Enable BasePress: Ensure the plugin is active.
  2. Create Contributor:
    wp user create attacker attacker@example.com --role=contributor --user_pass=password123
    
  3. Initialize KB: Create a Knowledge Base via the plugin settings (required for the post type to function correctly).
  4. Create Draft:
    wp post create --post_type=knowledgebase --post_title="Exploit Article" --post_status=draft --post_author=[ATTACKER_ID]
    

7. Expected Results

  • The malicious script (<script>alert(1)</script>) is saved in the wp_postmeta table.
  • When an Admin or any visitor views the Knowledge Base article or the Article List in the admin dashboard, the script executes.
  • Admin Context: If executed in the admin dashboard, the script could perform actions like creating a new administrator user.

8. Verification Steps

After performing the HTTP request, verify the storage via WP-CLI:

# Check if the payload is in the database
wp post meta list [POST_ID] --format=json | grep "script"

9. Alternative Approaches

  • Shortcode Attribute XSS: If the sink is in a shortcode, a Contributor can simply create a post containing:
    [basepress_search placeholder='"><script>alert(1)</script>'] (inferred attribute).
  • Icon Classes: BasePress often uses FontAwesome or custom icons. If the icon class selection is handled via a text input in the UI, inject the payload there: fa-book" onmouseover="alert(1)".
  • Knowledge Base Title: If the title of the Knowledge Base itself is vulnerable, use the plugin's AJAX settings save action (if permissions are incorrectly set to Contributor+).
Research Findings
Static analysis — not yet PoC-verified

Summary

The Knowledge Base documentation & wiki plugin – BasePress for WordPress is vulnerable to Stored Cross-Site Scripting due to insufficient input sanitization and output escaping on Knowledge Base article metadata. Authenticated attackers with Contributor-level access can inject arbitrary web scripts into custom fields that execute when an administrator or visitor views the affected article.

Vulnerable Code

// Inferred vulnerability in metadata saving logic
// basepress/admin/meta-boxes.php
if ( isset( $_POST['basepress_article_icon'] ) ) {
    update_post_meta( $post_id, '_basepress_article_icon', $_POST['basepress_article_icon'] );
}

---

// Inferred vulnerability in frontend or admin rendering logic
// basepress/public/render-article.php
$article_icon = get_post_meta( get_the_ID(), '_basepress_article_icon', true );
if ( $article_icon ) {
    echo '<span class="bp-icon ' . $article_icon . '"></span>';
}

Security Fix

--- a/basepress/admin/meta-boxes.php
+++ b/basepress/admin/meta-boxes.php
@@ -10,1 +10,1 @@
- update_post_meta( $post_id, '_basepress_article_icon', $_POST['basepress_article_icon'] );
+ update_post_meta( $post_id, '_basepress_article_icon', sanitize_text_field( $_POST['basepress_article_icon'] ) );

--- a/basepress/public/render-article.php
+++ b/basepress/public/render-article.php
@@ -15,1 +15,1 @@
- echo '<span class="bp-icon ' . $article_icon . '"></span>';
+ echo '<span class="bp-icon ' . esc_attr( $article_icon ) . '"></span>';

Exploit Outline

1. Authenticate as a user with Contributor-level permissions or higher. 2. Create a new Knowledge Base article or edit an existing draft (post_type=knowledgebase). 3. Use a proxy or the browser's developer tools to identify the POST request when saving the article, specifically targeting custom meta fields like 'basepress_article_icon'. 4. Inject an XSS payload into the metadata field (e.g., `"><script>alert(document.cookie)</script>`). 5. Save the post. 6. The script will be stored in the database and will execute whenever an Administrator views the article list in the backend or when the article is previewed/rendered on the frontend.

Check if your site is affected.

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