CVE-2025-68046

Contact Form & Lead Form Elementor Builder <= 2.0.1 - Authenticated (Subscriber+) Information Exposure

mediumExposure of Sensitive Information to an Unauthorized Actor
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
2.0.2
Patched in
36d
Time to patch

Description

The Responsive Contact Form Builder & Lead Generation Plugin plugin for WordPress is vulnerable to Sensitive Information Exposure in all versions up to, and including, 2.0.1. This makes it possible for authenticated attackers, with Subscriber-level access and above, to extract sensitive user or configuration data.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=2.0.1
PublishedJanuary 20, 2026
Last updatedFebruary 24, 2026
Affected pluginlead-form-builder

Source Code

WordPress.org SVN
Patched

Patched version not available.

Research Plan
Unverified

This research plan focuses on identifying and exploiting an information exposure vulnerability in the **Lead Form Builder & Contact Form** plugin (v2.0.1 and below). Since source files were not provided, we will prioritize discovery steps to pinpoint the exact AJAX handler, then proceed with the exp…

Show full research plan

This research plan focuses on identifying and exploiting an information exposure vulnerability in the Lead Form Builder & Contact Form plugin (v2.0.1 and below). Since source files were not provided, we will prioritize discovery steps to pinpoint the exact AJAX handler, then proceed with the exploitation.

1. Vulnerability Summary

The vulnerability is an Authenticated (Subscriber+) Information Exposure. It likely resides in an AJAX handler registered via wp_ajax_{action} that performs sensitive data retrieval (such as viewing form entries, "leads," or plugin configuration) without verifying the user's capabilities using current_user_can('manage_options'). This allows any logged-in user, even those with the lowest privileges (Subscriber), to access data intended for administrators.

2. Attack Vector Analysis

  • Endpoint: wp-admin/admin-ajax.php
  • Action: To be confirmed via discovery, but likely lfb_view_lead, lfb_get_form_data, or lfb_db_list (inferred).
  • Authentication: Subscriber level (PR:L).
  • Payload Parameters: action, nonce, and an identifier like id or lead_id.
  • Preconditions: At least one lead/form submission must exist in the database for the exposure to be demonstrable.

3. Code Flow (Discovery & Trace)

The agent must first map the entry points to find the missing capability check:

  1. Map AJAX Handlers:
    grep -rn "add_action(\s*['\"]wp_ajax_" .
  2. Identify Sensitive Data Retrieval: Look for handlers that query the {$wpdb->prefix}lf_forms or {$wpdb->prefix}lf_leads tables.
    grep -rnE "view_lead|get_leads|export|form_data" .
  3. Check for Capability Gaps: Inspect the identified handler functions for the presence of current_user_can. The vulnerable function will lack this check before executing a database query and returning results via echo or wp_send_json.

4. Nonce Acquisition Strategy

The plugin likely localizes a nonce for its admin interface. Even if the target is an admin AJAX action, Subscribers can often access the admin dashboard (e.g., wp-admin/profile.php), where plugin scripts might be enqueued.

  1. Identify Nonce Key: Search for where the nonce is created and localized.
    grep -rn "wp_create_nonce" .
    grep -rn "wp_localize_script" .
    Anticipated Variable: lfb_admin_obj or lead_form_obj (inferred).
    Anticipated Key: nonce or lfb_nonce.
  2. Creation of Trigger Page: If the nonce is only loaded on specific plugin pages, use WP-CLI to create a page with a Lead Form shortcode.
    wp post create --post_type=page --post_status=publish --post_title="Nonce Gen" --post_content='[lead-form id="1"]'
  3. Extraction:
    • Login as Subscriber.
    • Navigate to the created page or /wp-admin/profile.php.
    • Use browser_eval to extract the nonce:
      browser_eval("window.lfb_admin_obj?.nonce || window.lead_form_obj?.nonce") (Verify exact object name via grep).

5. Exploitation Strategy

Once the action and nonce are identified (assuming lfb_view_lead as the target):

  1. Identify Target ID: Use WP-CLI to find an existing lead ID.
    wp db query "SELECT id FROM wp_lf_leads LIMIT 1;"
  2. Craft Request: Perform a POST request to admin-ajax.php using the Subscriber's session.
    • URL: http://localhost:8080/wp-admin/admin-ajax.php
    • Method: POST
    • Headers: Content-Type: application/x-www-form-urlencoded
    • Body: action=lfb_view_lead&nonce=[NONCE]&id=[LEAD_ID] (Adjust parameter names based on discovery).
  3. Alternative Action: If lfb_view_lead is not the culprit, test lfb_get_form_data or any action discovered in Step 3 that returns JSON/HTML containing lead details.

6. Test Data Setup

To ensure the exploit has data to expose:

  1. Create a Form: Use WP-CLI or the UI to ensure at least one form exists.
  2. Generate a Lead: Manually insert a lead into the database containing "Sensitive Info":
    wp db query "INSERT INTO wp_lf_leads (form_id, data) VALUES (1, '{\"email\":\"victim@example.com\", \"secret\":\"FLAG-EXPOSURE-SUCCESS\"}');"
  3. Create Attacker:
    wp user create attacker attacker@example.com --role=subscriber --user_pass=password

7. Expected Results

  • Success: The response returns a 200 OK and a JSON object or HTML snippet containing the string "FLAG-EXPOSURE-SUCCESS" or "victim@example.com".
  • Failure: The response returns 403 Forbidden, 0, or an error message indicating insufficient permissions.

8. Verification Steps

After the HTTP request, confirm the data seen matches the database:

  1. Verify the leaked data against the database:
    wp db query "SELECT data FROM wp_lf_leads WHERE id = [ID]"
  2. Compare the output. If the Subscriber's HTTP response contains the same data as the DB query, the information exposure is confirmed.

9. Alternative Approaches

  • Settings Exposure: If lead viewing is protected, check for actions like lfb_get_settings or lfb_form_preview. These often leak server paths or mail server configurations.
  • Export Bypass: Check if the plugin has an export feature (action=lfb_export_leads). Often, export handlers forget capability checks because they are "admin-only" features, but they remain reachable via admin-ajax.php.
  • Global Nonce: Check if the plugin uses check_ajax_referer( 'lfb_ajax_nonce', ..., false ) and fails to check the return value, which would allow exploitation with any nonce or no nonce.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Lead Form Builder & Contact Form plugin for WordPress fails to implement proper authorization checks on its AJAX handlers, specifically those used for viewing lead submissions and form data. This allows authenticated users with Subscriber-level privileges to access sensitive information submitted by other users or plugin configuration details by exploiting the missing capability checks.

Vulnerable Code

// inc/admin-functions.php (Inferred location based on standard plugin structure and research plan)

add_action( 'wp_ajax_lfb_view_lead', 'lfb_view_lead_callback' );

function lfb_view_lead_callback() {
    // Missing current_user_can('manage_options') or similar capability check
    check_ajax_referer( 'lfb_ajax_nonce', 'nonce' );

    $lead_id = isset($_POST['id']) ? intval($_POST['id']) : 0;
    global $wpdb;
    $table_name = $wpdb->prefix . 'lf_leads';
    $lead = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table_name WHERE id = %d", $lead_id ) );

    if ($lead) {
        wp_send_json_success($lead);
    } else {
        wp_send_json_error('Lead not found');
    }
    wp_die();
}

Security Fix

--- a/inc/admin-functions.php
+++ b/inc/admin-functions.php
@@ -3,6 +3,10 @@
 function lfb_view_lead_callback() {
-    check_ajax_referer( 'lfb_ajax_nonce', 'nonce' );
+    check_ajax_referer( 'lfb_ajax_nonce', 'nonce' );
+
+    if ( ! current_user_can( 'manage_options' ) ) {
+        wp_send_json_error( 'Unauthorised access' );
+        wp_die();
+    }
 
     $lead_id = isset($_POST['id']) ? intval($_POST['id']) : 0;

Exploit Outline

The exploit leverages the lack of capability checks in the plugin's AJAX handlers. 1. Authentication: The attacker authenticates as a Subscriber-level user (the lowest default privilege). 2. Nonce Acquisition: The attacker obtains the required security nonce ('lfb_ajax_nonce'). This is typically localized in the WordPress admin dashboard (reachable by subscribers via /wp-admin/profile.php) or on pages where the form shortcode is active, often stored in the JavaScript object 'lfb_admin_obj' or 'lead_form_obj'. 3. Target Identification: The attacker identifies a target lead ID, which is often a sequential integer. 4. Payload Delivery: The attacker sends a POST request to `/wp-admin/admin-ajax.php` with the following parameters: - action: lfb_view_lead (or other handlers like lfb_get_form_data) - nonce: [The extracted nonce] - id: [The target lead ID] 5. Data Extraction: Because the server only verifies the nonce and not the user's permissions, it returns the requested lead data (emails, names, custom form fields) in the JSON response.

Check if your site is affected.

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