CVE-2025-64630

Business Directory <= 6.4.19 - Missing Authorization

mediumMissing Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
6.4.20
Patched in
6d
Time to patch

Description

The Business Directory Plugin – Easy Listing Directories for WordPress plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 6.4.19. This makes it possible for authenticated attackers, with Author-level access and above, to perform an unauthorized action.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=6.4.19
PublishedDecember 15, 2025
Last updatedDecember 20, 2025

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan - CVE-2025-64630 ## 1. Vulnerability Summary **CVE-2025-64630** is a Missing Authorization vulnerability in the **Business Directory Plugin** (versions <= 6.4.19). The vulnerability allows authenticated users with **Author-level** permissions or higher to perform unauth…

Show full research plan

Exploitation Research Plan - CVE-2025-64630

1. Vulnerability Summary

CVE-2025-64630 is a Missing Authorization vulnerability in the Business Directory Plugin (versions <= 6.4.19). The vulnerability allows authenticated users with Author-level permissions or higher to perform unauthorized actions, likely related to listing management or directory configuration, due to insufficient capability checks in an AJAX handler or a specific administrative function.

In Business Directory Plugin, many operations are handled via a central AJAX dispatcher or specific wp_ajax_ hooks. The missing authorization implies that a function intended for Administrators (who have manage_options) is accessible to Authors because it either lacks a current_user_can() check or uses an insufficiently restrictive capability (like edit_posts).

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Authentication: Author-level credentials (username/password required).
  • Vulnerable Action: (Inferred) An action related to modifying listing metadata, status, or featured levels, such as wpbdp_admin_ajax or a specific listing-flagging action.
  • Payload Parameters:
    • action: The specific AJAX action (e.g., wpbdp_set_listing_featured or similar).
    • listing_id / post_id: The ID of a listing to modify.
    • nonce: A security nonce required for the AJAX action.
  • Preconditions: The attacker must have an account with the Author role. The target listing should ideally belong to another user (e.g., the Administrator) to demonstrate unauthorized modification.

3. Code Flow

  1. Entry Point: The request hits admin-ajax.php with a registered action.
  2. Hook Registration: The plugin registers AJAX handlers in includes/class-business-directory.php or includes/admin/class-admin-listings.php using add_action( 'wp_ajax_...' ).
  3. Dispatching: The request is routed to a callback function (e.g., WPBDP_Admin_Listings::ajax_callback).
  4. The Vulnerability: The callback function performs sensitive operations (like updating post meta or changing post status) without calling current_user_can( 'manage_options' ) or checking if the current user is the author of the listing_id provided in the request.
  5. Sink: Functions like update_post_meta(), wp_update_post(), or internal plugin methods like WPBDP_Listing::set_flag() are executed.

4. Nonce Acquisition Strategy

Business Directory Plugin typically enqueues admin scripts that contain nonces in the wpbdp_admin or wpbdp_global JavaScript objects.

  1. Identify Script Localization: Search the source for wp_localize_script to find the admin nonce key.
    • Likely Variable: window.wpbdp_admin or window.wpbdp_global.
    • Likely Key: nonce.
  2. Access the Admin Dashboard: Log in as the Author user and navigate to the Business Directory section of the WordPress admin panel (/wp-admin/edit.php?post_type=wpbdp_listing).
  3. Extract Nonce:
    // Use browser_eval to extract the nonce
    const nonce = window.wpbdp_admin?.nonce || window.wpbdp_global?.nonce;
    
  4. Identify the Action String: In the plugin source, look for check_ajax_referer( 'wpbdp-admin-ajax', ... ) or wp_verify_nonce( ..., 'wpbdp-listing-flag' ) to identify the correct nonce action context.

5. Exploitation Strategy

The goal is to demonstrate that an Author can modify a listing that they do not own (e.g., changing its "Featured" status or expiration).

Step-by-Step Plan:

  1. Setup Phase:
    • Create an Administrator user.
    • Create an Author user.
    • As the Administrator, create a Business Directory listing (post_type=wpbdp_listing). Record its ID.
  2. Authentication Phase:
    • Log in to the WordPress site as the Author via the browser_navigate and login tools.
  3. Nonce Extraction:
    • Navigate to the listings page in the admin area: /wp-admin/edit.php?post_type=wpbdp_listing.
    • Use browser_eval to extract the wpbdp_admin.nonce.
  4. Execution Phase:
    • Use http_request to send a POST request to admin-ajax.php.
    • Target Action (Likely Candidate): wpbdp-listing-set-flag or wpbdp_admin_ajax.
    • Payload Example:
      POST /wp-admin/admin-ajax.php HTTP/1.1
      Content-Type: application/x-www-form-urlencoded
      
      action=wpbdp_admin_ajax&handler=listings__set_flag&listing_id=[ADMIN_LISTING_ID]&flag=featured&nonce=[EXTRACTED_NONCE]
      
      (Note: The exact handler and flag names must be verified in the source code.)

6. Test Data Setup

  • Users:
    • admin_user (Administrator)
    • attacker_author (Author)
  • Listing:
    • Title: "Admin's Premium Listing"
    • Author: admin_user
    • Featured Status: false (default)
  • Plugin Config: Ensure Business Directory is active and the Author role has access to view the listings menu in the backend (default behavior).

7. Expected Results

  • Response: The server returns a 200 OK with a JSON body indicating success (e.g., {"success": true}).
  • Effect: The listing belonging to the Administrator now has the "Featured" flag set (or its status changed), which the Author should not be able to perform.

8. Verification Steps

After the HTTP request, use WP-CLI to verify the state change:

# Check if the listing's featured status has changed in post meta
wp post meta get [ADMIN_LISTING_ID] _wpbdp[featured_level]
# Or check the listing flags
wp eval "echo WPBDP_Listing::get([ADMIN_LISTING_ID])->get_flag('featured');"

9. Alternative Approaches

If the wpbdp_admin_ajax dispatcher is not the vulnerability:

  • Search for other AJAX actions: grep -rn "wp_ajax_" . | grep "listing"
  • Look for status change handlers: Look for functions handling the "Published" to "Pending" or "Expired" transitions.
  • Check for "Manual Renewal": Sometimes Authors can bypass payment or authorization for renewing listings they don't own by triggering renewal AJAX actions.
  • Verify specific flags: If "featured" is protected, try "sticky", "verified", or modifying the "expiration date" metadata directly if an AJAX action allows meta_key manipulation.

Check if your site is affected.

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