CVE-2025-62122

Trash Duplicate and 301 Redirect <= 1.9.1 - Missing Authorization

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

Description

The Trash Duplicate and 301 Redirect plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 1.9.1. 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.9.1
PublishedDecember 31, 2025
Last updatedJanuary 5, 2026
Research Plan
Unverified

Since the source code for **Trash Duplicate and 301 Redirect <= 1.9.1** is not provided, this research plan is based on the vulnerability description (Missing Authorization), the CVSS score (5.3 - Unauthenticated), and standard WordPress plugin architecture. ### 1. Vulnerability Summary The "Trash …

Show full research plan

Since the source code for Trash Duplicate and 301 Redirect <= 1.9.1 is not provided, this research plan is based on the vulnerability description (Missing Authorization), the CVSS score (5.3 - Unauthenticated), and standard WordPress plugin architecture.

1. Vulnerability Summary

The "Trash Duplicate and 301 Redirect" plugin provides functionality to identify and trash duplicate posts and manage redirects. The vulnerability is a Missing Authorization flaw, which occurs when a sensitive function (likely an AJAX handler or a initialization hook) performs administrative actions (like trashing posts or changing settings) without verifying if the user has the necessary permissions (current_user_can()) or without verifying a valid CSRF nonce.

Because the severity is marked as unauthenticated access, the plugin likely registers a wp_ajax_nopriv_ hook or performs an action inside an admin_init or init hook that doesn't check the user's login status.

2. Attack Vector Analysis

  • Endpoint: wp-admin/admin-ajax.php (for AJAX-based flaws) or any front-end page (if hooked to init/wp_loaded).
  • Action Name (Inferred): Likely contains keywords such as trash, duplicate, redirect, process, or tdr. Examples: tdr_trash_duplicates, tdr_save_redirect.
  • Parameter: An action parameter in a POST/GET request, plus potential IDs for posts to be trashed.
  • Authentication: None required (Unauthenticated).
  • Preconditions: The plugin must be active.

3. Code Flow (Inferred)

  1. Entry Point: The plugin registers a hook: add_action( 'wp_ajax_nopriv_[ACTION_NAME]', 'callback_function' ); or add_action( 'admin_init', 'callback_function' );.
  2. Trigger: An unauthenticated attacker sends a request to admin-ajax.php?action=[ACTION_NAME].
  3. Vulnerable Function: The callback_function executes. It fails to call current_user_can( 'manage_options' ).
  4. Action: The function performs a database operation (e.g., calling wp_trash_post() or updating the wp_options table) based on user-supplied parameters.
  5. Sink: Database modification or post status change.

4. Nonce Acquisition Strategy

If the plugin is vulnerable to unauthenticated access, it is highly probable that it either:

  1. Completely lacks a nonce check.
  2. Uses a nonce that is exposed on the frontend.

Discovery Steps for the Agent:

  1. Search for AJAX registrations: grep -rn "wp_ajax_nopriv" wp-content/plugins/trash-duplicate-and-301-redirect/.
  2. Check the callback for check_ajax_referer or wp_verify_nonce.
  3. If a nonce is required, check if it's localized: grep -rn "wp_localize_script" wp-content/plugins/trash-duplicate-and-301-redirect/.
  4. If localized, identify the JS variable (e.g., tdr_obj) and the key (e.g., nonce).
  5. Browser Extraction:
    • Create a post/page to see if the script loads.
    • Use browser_eval("window.tdr_obj?.nonce").

5. Exploitation Strategy

The goal is to trigger the unauthorized trashing of posts or modification of redirects.

Step 1: Identification
Locate the vulnerable action by searching the source:

grep -rE "wp_ajax_nopriv|admin_init|wp_loaded" wp-content/plugins/trash-duplicate-and-301-redirect/

Step 2: Payload Construction
Assuming an AJAX action named tdr_trash_duplicates is found:

  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Method: POST
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body: action=tdr_trash_duplicates&nonce=[NONCE_IF_FOUND]&post_type=post (Parameters determined by auditing the found callback).

Step 3: Execution
Use http_request to send the payload.

6. Test Data Setup

To verify the exploit, we need duplicate content to "trash":

  1. Create a target post: wp post create --post_title="Original Post" --post_content="Content" --post_status=publish
  2. Create a duplicate post: wp post create --post_title="Original Post" --post_content="Content" --post_status=publish
  3. Record IDs: Use wp post list to get the IDs of the posts.
  4. Confirm status: Ensure they are currently publish.

7. Expected Results

  • The HTTP response should return a success indicator (e.g., {"success":true} or a 200 OK with a specific body).
  • The targeted duplicate posts should have their status changed from publish to trash.

8. Verification Steps

After the exploit attempt, verify the state using WP-CLI:

# Check if any posts were moved to trash
wp post list --post_status=trash

# Check specific IDs (if targeted)
wp post get [ID] --field=post_status

9. Alternative Approaches

If no wp_ajax_nopriv is found, the vulnerability might be in admin_init.

  • Scenario: A function hooked to admin_init checks $_GET['tdr_action'] but doesn't check is_admin() or permissions.
  • Exploit: http_request to http://localhost:8080/wp-admin/admin-ajax.php?tdr_action=trash_all (Requests to admin-ajax.php trigger admin_init even for unauthenticated users).

Grep for admin_init logic:

grep -rn "admin_init" wp-content/plugins/trash-duplicate-and-301-redirect/

Check the linked function for any processing of $_GET or $_POST without capability checks.

Research Findings
Static analysis — not yet PoC-verified

Summary

The Trash Duplicate and 301 Redirect plugin for WordPress is vulnerable to unauthorized access in versions up to and including 1.9.1 due to missing capability checks on administrative functions. This allows unauthenticated attackers to perform unauthorized actions, such as trashing duplicate posts or modifying redirect settings, by interacting with unprotected AJAX handlers or initialization hooks.

Exploit Outline

The exploit targets administrative functions that are exposed via AJAX or plugin initialization hooks without proper authorization. An unauthenticated attacker sends a POST or GET request to the WordPress backend (typically /wp-admin/admin-ajax.php) containing a specific 'action' parameter associated with the plugin's trashing or redirect management features. Because the plugin fails to verify the user's permissions using current_user_can() or validate a CSRF nonce, it processes the request as a legitimate administrative command, allowing the attacker to delete content or alter site redirects.

Check if your site is affected.

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