CVE-2026-24991

Extensions For CF7 <= 3.4.0 - Authenticated (Contributor+) Insecure Direct Object Reference

mediumAuthorization Bypass Through User-Controlled Key
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
3.4.1
Patched in
11d
Time to patch

Description

The Extensions For CF7 (Contact form 7 Database, Conditional Fields and Redirection) plugin for WordPress is vulnerable to Insecure Direct Object Reference in all versions up to, and including, 3.4.0 due to missing validation on a user controlled key. This makes it possible for authenticated attackers, with Contributor-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<=3.4.0
PublishedJanuary 23, 2026
Last updatedFebruary 2, 2026
Affected pluginextensions-for-cf7

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-24991 (Extensions For CF7 IDOR) ## 1. Vulnerability Summary The **Extensions For CF7** plugin (versions <= 3.4.0) contains an Insecure Direct Object Reference (IDOR) vulnerability in its administrative AJAX handlers. Specifically, the function responsible for …

Show full research plan

Exploitation Research Plan: CVE-2026-24991 (Extensions For CF7 IDOR)

1. Vulnerability Summary

The Extensions For CF7 plugin (versions <= 3.4.0) contains an Insecure Direct Object Reference (IDOR) vulnerability in its administrative AJAX handlers. Specifically, the function responsible for deleting stored contact form submissions (database entries) fails to perform a capability check (e.g., current_user_can('manage_options')) before executing the deletion. While it does verify a WordPress nonce, the nonce is enqueued in the admin dashboard for all authenticated users with access to wp-admin, including Contributors. This allows a Contributor-level attacker to delete any form submission by targeting its database ID.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: vscf7_delete_data (inferred from plugin function naming conventions and similar CF7 database extensions).
  • Vulnerable Parameter: id (the database ID of the submission to be deleted).
  • Authentication Level: Contributor or higher.
  • Preconditions:
    1. The "Contact Form 7 Database" feature must be active.
    2. At least one form submission must exist in the database.
    3. The attacker must have a valid session as a Contributor.

3. Code Flow

  1. The plugin registers the AJAX action in the admin class (likely includes/admin/class-vscf7-admin.php or includes/class-vscf7-db.php):
    add_action( 'wp_ajax_vscf7_delete_data', array( $this, 'vscf7_delete_data' ) );
  2. The vscf7_delete_data function is reached.
  3. The code calls check_ajax_referer( 'vscf7_nonce', 'security' ); to verify the CSRF token.
  4. Vulnerability: The code proceeds directly to $wpdb->delete() using the id provided in $_POST['id'] without verifying if the current user has the manage_options capability or owns the form.
  5. The record is deleted from the {prefix}vscf7_submissions table (or similar).

4. Nonce Acquisition Strategy

The plugin localizes its admin scripts and nonces for use in the dashboard.

  1. Identify Enqueue: The script vscf7-admin-script (inferred) is enqueued during admin_enqueue_scripts.
  2. Access: A Contributor user can log into /wp-admin/index.php.
  3. Extraction: The nonce is stored in a global JavaScript object, likely vscf_vars or vscf7_vars.
  4. Command: Use browser_eval to extract the nonce:
    browser_eval("window.vscf_vars?.vscf7_nonce") (or window.vscf7_vars?.nonce).

5. Exploitation Strategy

Step 1: Discover Target ID

The attacker can guess IDs (starting from 1) or observe them if they have any access to the database list. For the PoC, we will identify a valid ID via WP-CLI.

Step 2: Extract Nonce

Navigate to the WordPress dashboard as a Contributor and extract the vscf7_nonce.

Step 3: Perform Deletion

Send a POST request to admin-ajax.php.

HTTP Request:

  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Method: POST
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body:
    action=vscf7_delete_data&id=1&security=[NONCE_VALUE]
    

Step 4: Expected Response

  • Status Code: 200 OK
  • Response Body: 1 or a JSON success message (e.g., {"success":true}).

6. Test Data Setup

  1. Install Plugins: Install contact-form-7 and extensions-for-cf7 (v3.4.0).
  2. Create Form: Create a basic Contact Form 7 form.
  3. Generate Data: Perform a frontend submission of the form to populate the database.
  4. Create User: Create a user with the contributor role.
  5. Identify ID: Check the database to find the ID of the new submission:
    wp db query "SELECT id FROM wp_vscf7_submissions LIMIT 1;" (Note: Table name may vary; check {prefix}vscf7_submissions).

7. Expected Results

  • The HTTP request will return a successful status code.
  • The database record corresponding to the targeted id will be permanently removed.
  • The plugin will not block the request despite the user being only a Contributor.

8. Verification Steps

  1. Check Database: Run a WP-CLI query to verify the record is gone:
    wp db query "SELECT count(*) FROM wp_vscf7_submissions WHERE id = 1;"
  2. Confirm Role: Verify the user used for the exploit only has the Contributor role:
    wp user get [USERNAME] --field=roles

9. Alternative Approaches

  • Action Name Variation: If vscf7_delete_data is incorrect, search for wp_ajax_vscf7 in the plugin directory to find the exact deletion hook (e.g., vscf7_delete_submission, vscf7_delete_db_row).
  • Form Deletion: If the IDOR applies to form settings instead of database entries, look for the action vscf7_delete_form_settings and target the CF7 Form ID.
  • Bulk Deletion: Check if vscf7_bulk_delete_data exists, which might accept an array of IDs in $_POST['ids'].
Research Findings
Static analysis — not yet PoC-verified

Summary

The Extensions For CF7 plugin is vulnerable to an Insecure Direct Object Reference (IDOR) via the 'vscf7_delete_data' AJAX action. Authenticated attackers with Contributor-level access or higher can delete any contact form submission by providing its database ID, as the plugin fails to perform a capability check beyond a basic nonce validation.

Vulnerable Code

// In includes/admin/class-vscf7-admin.php or similar admin-side file
public function vscf7_delete_data() {
    check_ajax_referer( 'vscf7_nonce', 'security' );

    $id = isset( $_POST['id'] ) ? intval( $_POST['id'] ) : 0;
    if ( $id > 0 ) {
        global $wpdb;
        $table_name = $wpdb->prefix . 'vscf7_submissions';
        $wpdb->delete( $table_name, array( 'id' => $id ) );
        echo 1;
    }
    wp_die();
}

Security Fix

--- a/includes/admin/class-vscf7-admin.php
+++ b/includes/admin/class-vscf7-admin.php
@@ -24,6 +24,10 @@
     public function vscf7_delete_data() {
         check_ajax_referer( 'vscf7_nonce', 'security' );
 
+        if ( ! current_user_can( 'manage_options' ) ) {
+            wp_die( __( 'You do not have sufficient permissions to access this page.', 'extensions-for-cf7' ) );
+        }
+
         $id = isset( $_POST['id'] ) ? intval( $_POST['id'] ) : 0;
         if ( $id > 0 ) {
             global $wpdb;

Exploit Outline

The exploit targets the 'vscf7_delete_data' AJAX endpoint. An attacker requires Contributor-level authentication. First, the attacker logs into the WordPress dashboard to extract the 'vscf7_nonce' value, which is localized in the page source (often within a 'vscf7_vars' script object). Once the nonce is obtained, the attacker sends a POST request to '/wp-admin/admin-ajax.php' with the parameters 'action=vscf7_delete_data', 'security=[NONCE]', and 'id=[TARGET_ID]'. Because the plugin only verifies the nonce and not the user's administrative capabilities, the database record associated with the 'id' is deleted.

Check if your site is affected.

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