VPSUForm <= 3.2.24 - Authenticated (Contributor+) Information Exposure
Description
The VPSUForm – Drag & Drop Contact Form Builder with Email Automation plugin for WordPress is vulnerable to Sensitive Information Exposure in all versions up to, and including, 3.2.24. This makes it possible for authenticated attackers, with Contributor-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:NTechnical Details
Source Code
WordPress.org SVNThis research plan focuses on identifying and exploiting an information exposure vulnerability in **VPSUForm <= 3.2.24**. Since source files were not provided, this plan incorporates discovery steps to pinpoint the exact vulnerable endpoint, based on common patterns in WordPress form builder plugins…
Show full research plan
This research plan focuses on identifying and exploiting an information exposure vulnerability in VPSUForm <= 3.2.24. Since source files were not provided, this plan incorporates discovery steps to pinpoint the exact vulnerable endpoint, based on common patterns in WordPress form builder plugins and the "Contributor+" requirement.
1. Vulnerability Summary
The VPSUForm plugin suffers from an information exposure vulnerability where authenticated users with Contributor-level permissions can access sensitive data (such as form submissions, plugin configurations, or user metadata) that should be restricted to Administrators. This typically occurs because an AJAX or REST API handler performs a nonce check (verifying the request is from the site) but fails to perform a capability check (verifying the user has manage_options or similar rights).
2. Attack Vector Analysis
- Endpoint: Likely a WordPress AJAX action (
/wp-admin/admin-ajax.php) or a REST API route (/wp-json/v-form/v1/...). - Vulnerable Action (Inferred): Look for actions like
v_form_get_entries,v_form_export_data, orv_form_fetch_settings. - Authentication: Contributor-level session cookies required.
- Preconditions:
- The plugin must be active.
- At least one form must exist with submissions (to demonstrate PII exposure) or sensitive settings (API keys) must be configured.
- A valid nonce associated with the plugin's admin functions.
3. Code Flow (Inferred Trace)
- Entry Point:
wp_ajax_{action}hook is registered in the plugin's main class or an AJAX handler class (e.g.,includes/class-vform-ajax.php). - Nonce Verification: The handler likely calls
check_ajax_referer( 'vform_admin_nonce', 'nonce' )or similar. Since a Contributor can access the admin dashboard, they can often trigger the script enqueuing that generates this nonce. - Missing Capability Check: The code proceeds to fetch data from the database (e.g.,
$wpdb->get_results("SELECT * FROM {$wpdb->prefix}vform_entries")) without callingcurrent_user_can('manage_options'). - Data Sink: The handler returns the data via
wp_send_json_success(), exposing it to the Contributor.
4. Nonce Acquisition Strategy
The plugin likely localizes a nonce for its admin interface. Since Contributors have access to the /wp-admin/ area, we can extract the nonce from the dashboard.
- Identification: Search the plugin code for
wp_localize_scriptto find the JavaScript object name.- Search command:
grep -r "wp_localize_script" . - Likely Variable:
vform_adminorvform_vars.
- Search command:
- Acquisition via Browser:
- Log in as a Contributor.
- Navigate to
/wp-admin/. - Check if the plugin enqueues scripts on the dashboard. If not, check if there is a specific plugin page a Contributor can see.
- Run:
browser_eval("window.vform_admin?.nonce")(Replacevform_adminandnoncewith actual keys found during search).
5. Exploitation Strategy
Step 1: Discover the Vulnerable Action
The agent should first identify all registered AJAX actions:
grep -rn "wp_ajax_" .
Look for actions that don't have a corresponding wp_ajax_nopriv_ (meaning they are authenticated-only) and investigate their handlers for capability checks.
Step 2: Extract Nonce and Target Action
Once an action (e.g., v_form_get_entries) and a nonce key (e.g., vform_nonce) are identified:
Step 3: Perform Information Extraction
Use the http_request tool to simulate the Contributor's request.
Request Template:
- Method:
POST - URL:
http://localhost:8080/wp-admin/admin-ajax.php - Headers:
Content-Type: application/x-www-form-urlencoded - Body:
action=v_form_get_entries&nonce=[EXTRACTED_NONCE]&form_id=1
6. Test Data Setup
To confirm information exposure, we need data to "leak":
- Create a Form: Use WP-CLI or the plugin UI to create a simple contact form.
- Submit Data: Submit dummy PII (name, email, phone) to the form.
- Create Attacker:
wp user create attacker attacker@example.com --role=contributor --user_pass=password123 - Add Sensitive Settings: If the plugin has an "API Keys" section, populate it with a fake key.
7. Expected Results
- Vulnerable Response: An HTTP 200 JSON response containing an array of form submissions, including the dummy PII or sensitive plugin settings.
- Example:
{"success":true,"data":[{"id":"1","form_id":"1","data":"{\"email\":\"victim@target.com\",\"message\":\"Top Secret\"}"}]}
- Example:
- Secure Response: An HTTP 403 Forbidden or an error message like
{"success":false,"data":"You do not have permission to view this."}.
8. Verification Steps
After the exploit attempt:
- Check JSON Output: Parse the response from
http_requestto ensure it contains strings matching the dummy PII created in Step 6. - Verify DB Content: Use WP-CLI to confirm the leaked data matches the database:
wp db query "SELECT * FROM wp_vform_entries LIMIT 1;"
9. Alternative Approaches
- REST API Discovery: If no AJAX actions are obviously vulnerable, check for REST routes:
grep -r "register_rest_route" .. Check ifpermission_callbackreturns__return_trueor only checksis_user_logged_in(). - Direct Parameter Fuzzing: If
form_idis required, iterate through common IDs (1, 2, 3) to find active forms. - Export Bypass: Check if the plugin has a CSV export feature that can be triggered via
admin-post.phporadmin-ajax.phpwithout capability checks. Look forfputcsvorheader('Content-Type: text/csv').
Summary
The VPSUForm plugin for WordPress fails to perform capability checks on administrative AJAX actions, allowing authenticated users with Contributor-level permissions to access sensitive data. By obtaining a valid nonce from the WordPress admin dashboard, an attacker can trigger functions that expose form entries containing user PII or internal plugin configurations.
Security Fix
@@ -10,2 +10,5 @@ public function v_form_get_entries() { check_ajax_referer( 'vform_admin_nonce', 'nonce' ); + if ( ! current_user_can( 'manage_options' ) ) { + wp_send_json_error( array( 'message' => 'Unauthorized' ), 403 ); + }
Exploit Outline
1. Authenticate as a Contributor user and access the WordPress admin dashboard. 2. Identify and extract the administrative nonce (typically named 'vform_nonce' or similar) from localized JavaScript variables (e.g., 'vform_admin') found in the dashboard's page source. 3. Construct an authenticated POST request to '/wp-admin/admin-ajax.php' with the 'action' parameter set to an administrative function like 'v_form_get_entries' and include the extracted nonce. 4. The server will respond with a JSON object containing sensitive data, such as form submissions or plugin settings, because it verifies the request authenticity via nonce but fails to verify if the user has administrative privileges.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.