CVE-2025-62079

Export Categories & Taxonomies <= 1.0.3 - Missing Authorization

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
Unpatched
Patched in
N/A
Time to patch

Description

The Export Categories & Taxonomies plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 1.0.3. This makes it possible for unauthenticated attackers to perform an unauthorized action.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
None
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=1.0.3
PublishedDecember 31, 2025
Last updatedJanuary 5, 2026
Research Plan
Unverified

This research plan focuses on identifying and exploiting the **Missing Authorization** vulnerability in the **Export Categories & Taxonomies** plugin (<= 1.0.3). Since the vulnerability is rated with **Integrity: Low (I:L)** and **Confidentiality: None (C:N)**, the "unauthorized action" likely inv…

Show full research plan

This research plan focuses on identifying and exploiting the Missing Authorization vulnerability in the Export Categories & Taxonomies plugin (<= 1.0.3).

Since the vulnerability is rated with Integrity: Low (I:L) and Confidentiality: None (C:N), the "unauthorized action" likely involves triggering an export process or modifying an export-related setting rather than directly stealing data (which would be C:H).


1. Vulnerability Summary

  • Vulnerability: Missing Authorization (Missing Capability Check).
  • Plugin: Export Categories & Taxonomies (wp-export-categories-taxonomies).
  • Affected Versions: <= 1.0.3.
  • Root Cause: The plugin registers an AJAX action (likely via wp_ajax_nopriv_ or wp_ajax_) but fails to verify if the user has the necessary permissions (e.g., manage_options) before executing the logic.
  • Impact: Unauthenticated or low-privileged users can trigger administrative export functions or potentially manipulate plugin-specific actions.

2. Attack Vector Analysis

  • Endpoint: http://<target>/wp-admin/admin-ajax.php
  • Action (Inferred): Likely wp_ajax_ect_export_action or wp_ajax_export_categories_taxonomies.
  • Parameters:
    • action: The vulnerable AJAX hook identifier.
    • nonce / security: (If required) A CSRF token.
    • taxonomy: The target taxonomy to export.
  • Preconditions: The plugin must be active. A nonce may be required if check_ajax_referer is present, even if current_user_can is missing.

3. Code Flow (Inferred Trace)

  1. Entry Point: admin-ajax.php receives a POST/GET request with an action parameter.
  2. Hook Registration: The plugin's main file or an inclusion (e.g., wp-export-categories-taxonomies.php) registers the action:
    add_action('wp_ajax_nopriv_ect_export', 'ect_export_callback');
    add_action('wp_ajax_ect_export', 'ect_export_callback');
    
  3. Vulnerable Callback: The function ect_export_callback is executed.
  4. The Flaw: The function likely calls check_ajax_referer('ect_nonce', 'security') (providing CSRF protection) but fails to call if (!current_user_can('manage_options')) wp_die();.
  5. Execution: The function proceeds to perform the export or modification logic regardless of the requester's identity.

4. Nonce Acquisition Strategy

If the AJAX handler uses check_ajax_referer, we must find where the nonce is leaked to unauthenticated users.

  1. Identify Localization: Search the source for wp_localize_script.
    • Search Command: grep -rn "wp_localize_script" .
    • Expected JS Variable (Inferred): ect_ajax_vars or wp_ect_params.
    • Expected Key (Inferred): ect_nonce.
  2. Locate Script Enqueueing: Determine if the script is enqueued on the frontend (allowing unauthenticated access) or only in the admin dashboard.
    • If enqueued via wp_enqueue_scripts, it's available on the homepage.
    • If enqueued via admin_enqueue_scripts, we may need a Subscriber account OR the plugin might accidentally enqueue it on a login page/public shortcode.
  3. Extraction Method:
    • Step A: Create a public page with the plugin's main shortcode (if applicable) to force enqueuing.
      • Search for shortcode: grep -rn "add_shortcode" .
      • Example: wp post create --post_type=page --post_status=publish --post_content='[ect_export_form]'
    • Step B: Use browser_navigate to the page and browser_eval to extract the nonce:
      browser_eval("window.ect_ajax_vars?.ect_nonce || window.wp_ect_params?.security")
      

5. Exploitation Strategy

The goal is to trigger the unauthorized "Export" action via unauthenticated request.

  1. Discovery: First, identify the exact action name and parameters.
    • grep -r "wp_ajax" .
  2. Request Construction:
    • URL: http://<target>/wp-admin/admin-ajax.php
    • Method: POST
    • Content-Type: application/x-www-form-urlencoded
    • Payload (Inferred):
      action=ect_export&security=[NONCE]&taxonomy=category&format=csv
      
  3. Execution Tool: Use http_request.
  4. Bypass Check: If the code uses check_ajax_referer(..., ..., false) and ignores the return value, the security parameter can be omitted or be junk.

6. Test Data Setup

  1. Environment: Standard WordPress installation.
  2. Plugin: Install wp-export-categories-taxonomies version 1.0.3.
  3. Content: Create several categories and a custom taxonomy to ensure there is data to "export".
    wp term create category "Vulnerable Export Category"
    
  4. Visibility: If a shortcode is needed to get the nonce, create a page with it.

7. Expected Results

  • The server should return a 200 OK response.
  • The response body should contain exported data (e.g., CSV content) or a confirmation that an export file was generated/emailed/saved.
  • If I:L (Integrity Low) is the main impact, look for the server performing a state-changing action (e.g., resetting export logs or creating a file on the filesystem).

8. Verification Steps

  1. Response Analysis: Verify if the http_request response contains taxonomy data that should be restricted to admins.
  2. Filesystem Check: Check if the plugin created an export file in wp-content/uploads/.
    ls -R /var/www/html/wp-content/uploads/ | grep .csv
    
  3. Access Logs: Ensure the request was made without any Cookie header representing an authenticated session.

9. Alternative Approaches

  • Subscriber-Level Access: If wp_ajax_nopriv is not used, but wp_ajax_ is, test as a Subscriber user. The missing current_user_can check would still be a vulnerability (Privilege Escalation from Subscriber to Admin functionality).
  • Parameter Fuzzing: If the action name is found but it doesn't return data, try common export parameters: export_type, download, file_name, taxonomy_list.
  • Direct File Access: Check if the "action" triggers the creation of a file with a predictable name (e.g., taxonomy-export-[date].csv) in a public directory.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Export Categories & Taxonomies plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on its AJAX export functions. This allows unauthenticated attackers to trigger administrative export processes, which can lead to unauthorized state changes such as the generation of export files on the server.

Vulnerable Code

// Inferred from plugin hook registration and research plan
add_action('wp_ajax_nopriv_ect_export', 'ect_export_callback');
add_action('wp_ajax_ect_export', 'ect_export_callback');

function ect_export_callback() {
    // Missing current_user_can('manage_options') check
    check_ajax_referer('ect_nonce', 'security');

    $taxonomy = $_POST['taxonomy'];
    // Proceed to perform export logic...
}

Security Fix

--- a/wp-export-categories-taxonomies.php
+++ b/wp-export-categories-taxonomies.php
@@ -10,6 +10,10 @@
 function ect_export_callback() {
+    if ( ! current_user_can( 'manage_options' ) ) {
+        wp_die( __( 'You do not have permission to perform this action.' ) );
+    }
     check_ajax_referer('ect_nonce', 'security');
 
     $taxonomy = $_POST['taxonomy'];

Exploit Outline

1. Scan the site's frontend source code for localized script data (typically injected via wp_localize_script) to find the AJAX nonce (e.g., 'ect_nonce') and the action identifier (e.g., 'ect_export'). 2. Construct a POST request to the WordPress AJAX endpoint: /wp-admin/admin-ajax.php. 3. In the request body, include the 'action' parameter set to the vulnerable hook, the 'security' parameter with the leaked nonce, and relevant parameters such as 'taxonomy'. 4. Execute the request as an unauthenticated user; the server will process the administrative export logic despite the lack of a valid session or capability check.

Check if your site is affected.

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