CVE-2026-3831

Database for Contact Form 7, WPforms, Elementor forms <= 1.4.9 - Missing Authorization to Authenticated (Contributor+) Sensitive Information Exposure via Shortcode

mediumMissing Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
1.5.0
Patched in
1d
Time to patch

Description

The Database for Contact Form 7, WPforms, Elementor forms plugin for WordPress is vulnerable to unauthorized access of data due to a missing capability check on the entries_shortcode() function in all versions up to, and including, 1.4.9. This makes it possible for authenticated attackers, with Contributor-level access and above, to extract all form submissions - including names, emails, phone numbers.

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<=1.4.9
PublishedMarch 31, 2026
Last updatedApril 1, 2026
Affected plugincontact-form-entries

What Changed in the Fix

Changes introduced in v1.5.0

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Research Plan: CVE-2026-3831 - Sensitive Information Exposure via Shortcode ## 1. Vulnerability Summary The **Database for Contact Form 7, WPforms, Elementor forms** plugin (up to version 1.4.9) is vulnerable to sensitive information exposure. The plugin registers a shortcode `[vx-entries]` via t…

Show full research plan

Research Plan: CVE-2026-3831 - Sensitive Information Exposure via Shortcode

1. Vulnerability Summary

The Database for Contact Form 7, WPforms, Elementor forms plugin (up to version 1.4.9) is vulnerable to sensitive information exposure. The plugin registers a shortcode [vx-entries] via the entries_shortcode() function in the vxcf_form class. This function fails to perform any authorization checks (e.g., current_user_can()) to verify if the user viewing the rendered shortcode has the permissions to access form submissions. Consequently, any user with Contributor level access (who can create posts and use shortcodes) can display and extract all form entries (names, emails, phone numbers) from the database by placing the shortcode in a post and previewing it.

2. Attack Vector Analysis

  • Target Endpoint: Frontend post rendering (typically via a Post Preview or a published page).
  • Shortcode: [vx-entries]
  • Required Authentication: Contributor-level user.
  • Vulnerability Type: Missing Authorization.
  • Impact: Full exposure of all form submissions captured by the plugin from various sources (Contact Form 7, WPForms, Elementor, etc.).

3. Code Flow

  1. Registration: In contact-form-entries.php, the setup_main() method registers the shortcode:
    add_shortcode('vx-entries', array($this, 'entries_shortcode'));
    
  2. Execution: When a post containing [vx-entries] is rendered (e.g., during the_content filter), WordPress calls the entries_shortcode() method in the vxcf_form class.
  3. Vulnerable Sink: Inside entries_shortcode(), the code queries the database for records in the entries table (likely wp_vxcf_leads or similar, based on self::$id = 'vxcf_leads') and returns an HTML table of the results.
  4. Missing Check: The function lacks a check for capabilities such as vxcf_leads_read_entries (defined in includes/install.php) before returning the data.

4. Nonce Acquisition Strategy

This vulnerability does not require a nonce.

  • Shortcodes are processed by the WordPress core engine during content rendering.
  • An attacker simply needs to be able to create or edit a post and then view the output.
  • Since the goal is to view data rendered on the page, the only "token" needed is a valid session cookie for a Contributor-level user.

5. Exploitation Strategy

  1. Authentication: Authenticate as a user with the Contributor role.
  2. Post Creation: Create a new post (draft) containing the payload [vx-entries].
  3. Preview Trigger: Obtain the preview URL for the newly created post.
  4. Data Extraction: Perform a GET request to the preview URL. The response will contain an HTML table with all form entries stored in the database.

6. Test Data Setup

To verify the exploit, the database must contain at least one form entry.

  1. Create Dummy Entry: Use WP-CLI to simulate a form submission. The plugin hooks into various form events. We can trigger the internal crmperks_forms_new_submission filter or manually insert a row.
    # Create a dummy entry via the plugin's own logic (vxcf_form::create_entry_vf)
    wp eval 'apply_filters("crmperks_forms_new_submission", array("first_name" => "Secret", "last_name" => "User", "email" => "vulnerable@example.com"), "manual_test", array());'
    
  2. Create Contributor User:
    wp user create attacker attacker@example.com --role=contributor --user_pass=password123
    

7. Expected Results

  • The GET request to the post preview will return a 200 OK response.
  • The response body will contain the sensitive dummy data (e.g., "vulnerable@example.com") inside a table structure.
  • The data will be accessible despite the Contributor user lacking the vxcf_leads_read_entries capability.

8. Verification Steps

  1. Login and Session: Use http_request to login as attacker.
  2. Create Post:
    # Example using WP-CLI to create the post for the attacker
    wp post create --post_type=post --post_status=draft --post_author=$(wp user get attacker --field=ID) --post_content='[vx-entries]' --post_title='Leaked Entries'
    
  3. Retrieve ID and Preview:
    POST_ID=$(wp post list --post_author=$(wp user get attacker --field=ID) --post_status=draft --format=ids)
    
  4. Access Preview: Use http_request as the attacker to:
    GET /index.php?p=$POST_ID&preview=true
  5. Confirm Leak: Check if "vulnerable@example.com" exists in the HTML.

9. Alternative Approaches

  • ID-specific Leak: If the shortcode supports an id attribute (e.g., [vx-entries id="1"]), try to target specific forms if "show all" is not the default.
  • Block Editor: If the classic editor is disabled, use the REST API to create the post with the shortcode blocks.
  • Direct AJAX/CSV: If the shortcode renders a "Download CSV" button (referenced in readme.txt), check if the CSV generation logic in init():
    if(!empty($_GET['vx_crm_form_action']) && $_GET['vx_crm_form_action'] == 'download_csv'){ ... }
    
    also lacks authorization. This would allow for a much cleaner data exfiltration. The init() hook check for download_csv in contact-form-entries.php appears to only check for a vx_crm_key but not for capabilities.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Database for Contact Form 7, WPforms, Elementor forms plugin for WordPress fails to implement proper authorization checks within its shortcode handler. This allows authenticated users with Contributor-level access to view all captured form submissions (including sensitive data like emails and phone numbers) by embedding the [vx-entries] shortcode into a post and previewing or viewing it.

Vulnerable Code

// contact-form-entries.php line 204
public function entries_shortcode($atts){
    if(is_preview() && !current_user_can(vxcf_form::$id.'_read_entries')){
     return;   
    }
  $form_id='';
  if(!empty($atts['form-id'])){
  // ... (subsequent code queries and returns all database entries) ...

Security Fix

--- /home/deploy/wp-safety.org/data/plugin-versions/contact-form-entries/1.4.9/contact-form-entries.php	2026-03-22 05:24:00.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/contact-form-entries/1.5.0/contact-form-entries.php	2026-03-24 07:50:42.000000000 +0000
@@ -202,8 +202,13 @@
   update_option(vxcf_form::$type."_version", self::$version);
 }
 public function entries_shortcode($atts){
-    if(is_preview() && !current_user_can(vxcf_form::$id.'_read_entries')){
-     return;   
+     $post = get_post();
+    if ( ! $post ) {
+        return '';
+    }
+    // Check if the POST AUTHOR has the _read_entries capability
+    if ( ! user_can( $post->post_author, vxcf_form::$id . '_read_entries' ) ) { //is_preview()
+        return '';
     }
   $form_id='';
   if(!empty($atts['form-id'])){

Exploit Outline

To exploit this vulnerability, an attacker requires at least Contributor-level privileges, which allow for post creation and shortcode usage. The attacker creates a new post or draft and inserts the '[vx-entries]' shortcode into the content. Because the plugin only performed a weak capability check restricted to the 'is_preview()' condition (and even then, improperly), viewing the resulting post or its preview renders a table containing all form submissions from the database. No special nonces or complex payloads are required beyond the shortcode itself.

Check if your site is affected.

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