CVE-2025-14001

WP Duplicate Page <= 1.8 - Missing Authorization to Authenticated (Contributor+) Arbitrary Post Duplication

mediumMissing Authorization
5.4
CVSS Score
5.4
CVSS Score
medium
Severity
1.8.1
Patched in
1d
Time to patch

Description

The WP Duplicate Page plugin for WordPress is vulnerable to unauthorized modification of data due to missing capability checks on the 'duplicateBulkHandle' and 'duplicateBulkHandleHPOS' functions in all versions up to, and including, 1.8. This makes it possible for authenticated attackers, with Contributor-level access and above, to duplicate arbitrary posts, pages, and WooCommerce HPOS orders even when their role is explicitly excluded from the plugin's "Allowed User Roles" setting, potentially exposing sensitive information and allowing duplicate fulfillment of WooCommerce orders.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=1.8
PublishedJanuary 12, 2026
Last updatedJanuary 13, 2026
Affected pluginwp-duplicate-page

What Changed in the Fix

Changes introduced in v1.8.1

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan - CVE-2025-14001 ## 1. Vulnerability Summary The **WP Duplicate Page** plugin (up to v1.8) contains a missing authorization vulnerability in its bulk duplication handlers. While the plugin provides a "Allowed User Roles" setting to restrict who can duplicate content, th…

Show full research plan

Exploitation Research Plan - CVE-2025-14001

1. Vulnerability Summary

The WP Duplicate Page plugin (up to v1.8) contains a missing authorization vulnerability in its bulk duplication handlers. While the plugin provides a "Allowed User Roles" setting to restrict who can duplicate content, the functions duplicateBulkHandle and duplicateBulkHandleHPOS in includes/Classes/ButtonDuplicate.php fail to invoke the Utils::isCurrentUserAllowedToCopy() check or any WordPress capability check (e.g., current_user_can).

This allows any authenticated user with access to the WordPress admin (Contributor level and above) to duplicate arbitrary posts, pages, or WooCommerce orders by manually triggering the bulk action, even if their role is explicitly excluded in the plugin settings.

2. Attack Vector Analysis

  • Endpoint: wp-admin/edit.php (for posts/pages) or wp-admin/admin.php?page=wc-orders (for WooCommerce HPOS).
  • Action: wp_duplicate_page_bulk_action
  • Method: GET or POST.
  • Authentication: Contributor level or higher (any role that can access edit.php).
  • Vulnerable Parameters:
    • post[]: An array of Post IDs to duplicate.
    • action: Must be set to wp_duplicate_page_bulk_action.
    • _wpnonce: A standard WordPress bulk action nonce.
  • Precondition: The targeted post type must be enabled in the plugin's settings (njt_duplicate_post_types option). By default, the plugin enables this for post and page.

3. Code Flow

  1. Registration: ButtonDuplicate::addDuplicateButtonLink() (Line 36) registers the bulk action handler for all post types stored in the njt_duplicate_post_types option.
  2. Hook: It uses the filter handle_bulk_actions-edit-{$post_type} (Line 52), which WordPress core calls when a bulk action is submitted.
  3. Trigger: When a user submits a request to edit.php with action=wp_duplicate_page_bulk_action, WordPress core validates the generic bulk-posts nonce and then fires the filter.
  4. Sink: ButtonDuplicate::duplicateBulkHandle (Line 63) receives the request.
  5. Missing Check:
    • Line 64: It checks if the action is correct.
    • Line 67: It loops through $postIds.
    • Line 72: It calls CreateDuplicate::getInstance()->createDuplicate($post).
    • Vulnerability: Between lines 63 and 72, there is no check for Utils::isCurrentUserAllowedToCopy() or current_user_can('edit_post', $postId).

4. Nonce Acquisition Strategy

The vulnerability resides in a hook (handle_bulk_actions) that is managed by WordPress core. To trigger this hook, the attacker must provide a valid bulk action nonce for the specific screen (e.g., the edit-post screen).

  1. Role: Contributor.
  2. Action: Navigate to the Post list table.
  3. Extraction:
    • Use browser_navigate to http://vulnerable-hostname/wp-admin/edit.php.
    • Use browser_eval to extract the _wpnonce from the bulk action form.
    • JS Command: document.querySelector('#bulk-action-selector-top').closest('form').querySelector('input[name="_wpnonce"]').value
  4. Note: This is a standard WordPress CSRF protection, but because the attacker is an authenticated user (Contributor), they can legitimately obtain this nonce for their own session.

5. Exploitation Strategy

Step 1: Confirm Targeted Post Type

Ensure the target post type (e.g., post) is enabled for duplication.

wp option get njt_duplicate_post_types

Step 2: Extract Nonce

Navigate to the admin post list as a Contributor and grab the nonce.

Step 3: Trigger Duplication

Send a request to duplicate a post owned by an Administrator (e.g., Post ID 1).

Request Details:

  • URL: http://vulnerable-hostname/wp-admin/edit.php?s&post_status=all&post_type=post&action=wp_duplicate_page_bulk_action&post[]=1&_wpnonce=[EXTRACTED_NONCE]&action2=-1
  • Method: GET
  • Headers: Valid Contributor Cookies.

Step 4: HPOS Variant (If WooCommerce is present)

If targeting WooCommerce orders:

  • URL: http://vulnerable-hostname/wp-admin/admin.php?page=wc-orders&action=wp_duplicate_page_bulk_action&ids[]=ORDER_ID&_wpnonce=[EXTRACTED_NONCE]

6. Test Data Setup

  1. Admin Content: Create a "Private" or "Published" post as an administrator.
    • wp post create --post_type=post --post_title="Admin Secret Draft" --post_status=draft --post_author=1
  2. Attacker User: Create a user with the contributor role.
  3. Plugin Config: Ensure post is in the allowed types (usually default).
    • wp option update njt_duplicate_post_types '["post", "page"]'
  4. Role Restriction: (Optional) Configure the plugin to ONLY allow Administrators to copy, to prove the bypass.
    • wp option update njt_duplicate_roles '["administrator"]'

7. Expected Results

  • The server will respond with a redirect back to edit.php with the query parameter bulk_cloned=1.
  • A new post will be created in the database that is an exact clone of the Administrator's post.
  • The Contributor user will be able to see this new cloned post in their "Posts" list if the plugin sets the clone's author to the current user (common behavior) or if they simply view the IDs.

8. Verification Steps

Check the database for a new post with a similar title (usually "Copy of ...") and verify the creation:

wp post list --post_type=post --orderby=ID --order=DESC --limit=2

Verify the post_author of the duplicate. If it is the Contributor, they have successfully "stolen" or duplicated content they shouldn't have access to manipulate via the plugin.

9. Alternative Approaches

If the bulk action requires a POST request in certain WordPress environments:
POST Request:

  • URL: http://vulnerable-hostname/wp-admin/edit.php
  • Body (URL-encoded): action=wp_duplicate_page_bulk_action&post[]=1&_wpnonce=[NONCE]&post_type=post
  • Content-Type: application/x-www-form-urlencoded

If targeting duplicateBulkHandleHPOS, use ids[] instead of post[] as seen in Line 92.

Check if your site is affected.

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