CVE-2026-24542

Term Order <= 2.1.0 - Cross-Site Request Forgery

mediumCross-Site Request Forgery (CSRF)
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
2.2.0
Patched in
18d
Time to patch

Description

The Term Order plugin for WordPress is vulnerable to Cross-Site Request Forgery in versions up to, and including, 2.1.0. This is due to missing or incorrect nonce validation on a function. This makes it possible for unauthenticated attackers to perform an unauthorized action via a forged request granted they can trick a site administrator into performing an action such as clicking on a link.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=2.1.0
PublishedJanuary 24, 2026
Last updatedFebruary 10, 2026
Affected pluginwp-term-order
Research Plan
Unverified

This research plan outlines the technical steps to analyze and exploit CVE-2026-24542, a CSRF vulnerability in the **WP Term Order** plugin (<= 2.1.0). --- ### 1. Vulnerability Summary The **WP Term Order** plugin fails to implement or correctly verify WordPress nonces in its term reordering funct…

Show full research plan

This research plan outlines the technical steps to analyze and exploit CVE-2026-24542, a CSRF vulnerability in the WP Term Order plugin (<= 2.1.0).


1. Vulnerability Summary

The WP Term Order plugin fails to implement or correctly verify WordPress nonces in its term reordering functionality. Specifically, the AJAX handler responsible for saving the custom sort order of terms (categories, tags, or custom taxonomies) lacks a check_ajax_referer() or wp_verify_nonce() call. This allow an attacker to perform unauthorized term reordering by tricking a logged-in administrator into visiting a malicious page that submits a forged POST request to the site's AJAX endpoint.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: update-tax-order (inferred based on plugin purpose)
  • HTTP Method: POST
  • Payload Parameter: Likely order or tags (serialized string or array of term IDs).
  • Authentication Level: Administrator (victim must be logged in).
  • Preconditions: The site must have terms (e.g., Categories) created that the attacker wishes to reorder.

3. Code Flow (Inferred)

  1. Hook Registration: The plugin registers an AJAX action for authenticated users:
    add_action('wp_ajax_update-tax-order', 'wptaxorder_update_order'); (inferred function name).
  2. Entry Point: When an admin drags and drops terms in the UI, a POST request is sent to admin-ajax.php with action=update-tax-order.
  3. Missing Security Check: The callback function (e.g., wptaxorder_update_order) begins processing $_POST data without calling check_ajax_referer('some_nonce_action', 'security').
  4. Data Processing: The function iterates through the provided term IDs and updates the term_order (or menu_order) column in the wp_term_relationships or wp_terms table using $wpdb->update.
  5. Sink: Direct database update without verifying the request's origin via CSRF tokens.

4. Nonce Acquisition Strategy

Note: As this is a CSRF vulnerability, the exploit's success depends on the absence or bypass of a nonce.

If a nonce is present but "incorrectly validated" (e.g., wp_verify_nonce used but the result is not checked):

  1. Shortcode/Page Discovery: Identify where the plugin loads its reordering interface (usually the standard WordPress "Categories" or "Tags" pages in the admin dashboard).
  2. Execution Context: The agent should use browser_navigate to wp-admin/edit-tags.php?taxonomy=category.
  3. Variable Extraction: Use browser_eval to check for any localized data:
    browser_eval("window.wpTermOrderData || window.taxOrderConfig") (inferred names).
  4. Bypass Check: If a nonce is required but the plugin uses a generic action like -1, the agent can acquire a nonce for action -1 from any other plugin on the site.

5. Exploitation Strategy

The goal is to demonstrate that a POST request to the AJAX handler succeeds without a valid nonce.

Step-by-Step Plan:

  1. Identify IDs: Get the IDs of existing categories using WP-CLI.
  2. Craft Payload: Construct a POST request to admin-ajax.php.
  3. Execute via HTTP Request:
    // Payload example using http_request
    await http_request({
      url: "http://localhost:8080/wp-admin/admin-ajax.php",
      method: "POST",
      headers: {
        "Content-Type": "application/x-www-form-urlencoded"
      },
      body: "action=update-tax-order&order[]=TERM_ID_2&order[]=TERM_ID_1" // Adjust parameter names based on discovery
    });
    
  4. Verification: Check the order of terms in the database.

6. Test Data Setup

  1. Create Terms:
    wp term create category "Alpha"
    wp term create category "Beta"
    wp term create category "Gamma"
    
  2. Capture Initial State:
    wp term list category --fields=term_id,name,term_order --orderby=term_order
    

7. Expected Results

  • The http_request should return a 200 OK response, often containing 1 or {"success":true}.
  • No "403 Forbidden" or "-1" (default WordPress AJAX nonce failure) should be returned.
  • The term_order values in the database for the targeted terms should be updated to reflect the new order provided in the malicious request.

8. Verification Steps

After performing the http_request, run the following via WP-CLI:

# Check if the order changed from the initial state
wp term list category --fields=term_id,name,term_order --orderby=term_order

If the terms appear in the order sent by the exploit (e.g., Beta, Alpha, Gamma) instead of the creation order, the CSRF is confirmed.

9. Alternative Approaches

If the action name is not update-tax-order:

  1. Grep Search: Search the plugin directory for wp_ajax_:
    grep -rn "wp_ajax_" wp-content/plugins/wp-term-order/
  2. Parameter Search: Search for $_POST usage in the identified handler:
    grep -rn "\$_POST" wp-content/plugins/wp-term-order/
  3. JS Analysis: Check the plugin's JavaScript files for the AJAX call structure:
    grep -rn "ajax" wp-content/plugins/wp-term-order/ --include="*.js"
    Look for the data object containing the action string.
Research Findings
Static analysis — not yet PoC-verified

Summary

The WP Term Order plugin for WordPress fails to validate CSRF nonces in its AJAX handler for reordering taxonomy terms. This allows an attacker to trick a logged-in administrator into visiting a malicious link, which then triggers an unauthorized reordering of categories, tags, or custom taxonomies on the site.

Vulnerable Code

// Inferred from plugin version 2.1.0 and AJAX action structure

add_action('wp_ajax_update-tax-order', 'wptaxorder_update_order');

function wptaxorder_update_order() {
    // Vulnerability: Missing check_ajax_referer() or wp_verify_nonce() call
    
    if (isset($_POST['order'])) {
        $order = $_POST['order'];
        foreach ($order as $index => $term_id) {
            // Database update logic follows...
            $wpdb->update($wpdb->term_relationships, array('term_order' => $index), array('term_taxonomy_id' => $term_id));
        }
        echo '1';
        die();
    }
}

Security Fix

--- a/wp-term-order.php
+++ b/wp-term-order.php
@@ -105,6 +105,7 @@
 function wptaxorder_update_order() {
+	check_ajax_referer( 'wptaxorder-nonce', 'security' );
 	if ( isset( $_POST['order'] ) ) {
 		// ... existing update logic ...
 	}

Exploit Outline

The exploit targets the WordPress AJAX endpoint to manipulate taxonomy term ordering via a Cross-Site Request Forgery (CSRF) attack. 1. **Identify Target Action**: The plugin registers the `update-tax-order` AJAX action which lacks nonce verification. 2. **Payload Construction**: Construct a POST request to `/wp-admin/admin-ajax.php` containing the `action=update-tax-order` parameter and an `order[]` array containing term IDs in the attacker's desired sequence. 3. **Social Engineering**: The attacker hosts an auto-submitting HTML form or a malicious script on a third-party site. 4. **Execution**: An authenticated WordPress administrator is tricked into visiting the attacker's site while their session is active. 5. **Impact**: The browser automatically executes the POST request to the target WordPress site. Since there is no nonce validation, the server accepts the request as legitimate and updates the term order in the database according to the attacker's payload.

Check if your site is affected.

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