CVE-2026-3296

Everest Forms <= 3.4.3 - Unauthenticated PHP Object Injection via Form Entry Metadata

criticalDeserialization of Untrusted Data
9.8
CVSS Score
9.8
CVSS Score
critical
Severity
3.4.4
Patched in
1d
Time to patch

Description

The Everest Forms plugin for WordPress is vulnerable to PHP Object Injection in all versions up to, and including, 3.4.3 via deserialization of untrusted input from form entry metadata. This is due to the html-admin-page-entries-view.php file calling PHP's native unserialize() on stored entry meta values without passing the allowed_classes parameter. This makes it possible for unauthenticated attackers to inject a serialized PHP object payload through any public Everest Forms form field. The payload survives sanitize_text_field() sanitization (serialization control characters are not stripped) and is stored in the wp_evf_entrymeta database table. When an administrator views entries or views an individual entry, the unsafe unserialize() call processes the stored data without class restrictions.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=3.4.3
PublishedApril 7, 2026
Last updatedApril 8, 2026
Affected plugineverest-forms

What Changed in the Fix

Changes introduced in v3.4.4

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Research Plan: CVE-2026-3296 - Everest Forms Unauthenticated PHP Object Injection ## 1. Vulnerability Summary The **Everest Forms** plugin (versions <= 3.4.3) is vulnerable to **PHP Object Injection** due to the insecure use of the native PHP `unserialize()` function. The vulnerability exists in …

Show full research plan

Research Plan: CVE-2026-3296 - Everest Forms Unauthenticated PHP Object Injection

1. Vulnerability Summary

The Everest Forms plugin (versions <= 3.4.3) is vulnerable to PHP Object Injection due to the insecure use of the native PHP unserialize() function. The vulnerability exists in the way form entry metadata is retrieved and displayed in the WordPress administrative dashboard.

An unauthenticated attacker can submit a form containing a serialized PHP object payload in any field. This payload is stored in the wp_evf_entrymeta table. When an administrator views the "Entries" section of the plugin, the html-admin-page-entries-view.php file processes this stored metadata using unserialize() without restricting the allowed classes. This allows the execution of arbitrary code if a suitable POP (Property-Oriented Programming) gadget chain is present in the environment (e.g., within WordPress core or other active plugins).

2. Attack Vector Analysis

  • Endpoint: wp-admin/admin-ajax.php (Front-end form submission).
  • Action: everest_forms_submit_form (inferred action for form submission).
  • Vulnerable Parameter: Any form field parameter (e.g., form_fields[field_id]).
  • Authentication: None (Unauthenticated).
  • Preconditions:
    1. At least one Everest Forms form must be published and accessible on the frontend.
    2. An administrator must eventually view the submitted entry in the WP-Admin area.

3. Code Flow

  1. Submission (Unauthenticated):

    • The user submits a form on the frontend.
    • The request is processed by EVF_Frontend_Form_Handler::submit_form() (or similar class responsible for submission).
    • The plugin iterates through fields and applies sanitize_text_field().
    • Critical Note: sanitize_text_field() does not remove characters critical to PHP serialization (like O:, a:, {}).
    • The data is saved into the database table wp_evf_entrymeta.
  2. Triggering (Admin):

    • Administrator navigates to wp-admin/admin.php?page=evf-entries.
    • The plugin loads includes/admin/views/html-admin-page-entries-view.php.
    • The code retrieves entry meta: $entry_meta = $wpdb->get_results(...).
    • The code iterates through the meta values and calls unserialize( $meta_value->meta_value ).
    • The PHP Object Injection is triggered at this point.

4. Nonce Acquisition Strategy

Form submissions in Everest Forms are protected by a frontend nonce.

  1. Identify the Script/Variable: Everest Forms typically localizes parameters under the handle everest-forms-frontend.
  2. Target Variable: window.evf_frontend_params (inferred).
  3. Target Key: nonce.
  4. Acquisition Steps:
    • Use WP-CLI to create a form and a page containing that form's shortcode.
    • Use the browser_navigate tool to go to the newly created page.
    • Use browser_eval to extract the nonce:
      window.evf_frontend_params?.nonce || document.querySelector('#everest-forms-nonce')?.value
      
    • Note: If the CleanTalk addon is active, it enqueues a different nonce (everest_forms_clean_talk_nonce), but this is for admin settings and likely not the submission nonce.

5. Exploitation Strategy

Step 1: Payload Selection

Since we need to confirm the injection, we will use a gadget chain that produces an observable side effect. A common gadget for WordPress is GuzzleHttp\Cookie\CookieJar (if available) or a generic __destruct trigger that logs to a file. For initial PoC, a "dummy" serialized object can be used to confirm if unserialize is reached.

Payload Example (Generic):
O:8:"stdClass":1:{s:3:"abc";s:3:"def";}

Step 2: Submission Request

Submit the payload via the AJAX submission endpoint.

  • URL: http://<target>/wp-admin/admin-ajax.php
  • Method: POST
  • Content-Type: application/x-www-form-urlencoded
  • Parameters:
    • action: everest_forms_submit_form
    • everest_forms[id]: <form_id>
    • everest_forms_nonce: <extracted_nonce>
    • form_fields[<field_id>]: O:8:"stdClass":1:{s:3:"abc";s:3:"def";} (URL-encoded)

Step 3: Triggering

Login as an administrator and access the entry viewer.

  • URL: http://<target>/wp-admin/admin.php?page=evf-entries&view=entries&form_id=<form_id>

6. Test Data Setup

  1. Create a Form:
    wp evf-form create --title="Exploit Form" --status="publish"
    
    (Note: If evf-form command doesn't exist, use wp post create with post_type everest_forms and appropriate JSON in post_content.)
  2. Extract Form ID and Field ID: Retrieve the ID from the previous command or wp post list --post_type=everest_forms.
  3. Create a Public Page:
    wp post create --post_type=page --post_title="Contact" --post_content='[everest_form id="<form_id>"]' --post_status="publish"
    

7. Expected Results

  • The form submission should return a success JSON: {"success":true,...}.
  • Upon viewing entries as an admin, if a malicious gadget is used (e.g., one that calls wp_die()), the admin page will crash or display the wp_die message, confirming execution.
  • If using a dummy object, we can verify it was stored correctly in the database.

8. Verification Steps

  1. Database Check: Verify the payload is stored in the wp_evf_entrymeta table without being mangled.
    wp db query "SELECT * FROM $(wp db prefix)evf_entrymeta WHERE meta_value LIKE 'O:%';"
    
  2. Execution Check: Use a gadget that creates a file in wp-content/ and verify its existence using ls.

9. Alternative Approaches

  • Direct POST: Some versions allow submitting directly to the page containing the shortcode via a standard POST request (non-AJAX).
  • Different Entry Points: If evf-entries doesn't trigger it, try the individual entry view: wp-admin/admin.php?page=evf-entries&view=view-entry&entry_id=<entry_id>.
  • Gadget Chains: If GuzzleHttp isn't present, check for Requests (WordPress core) or other common libraries used by Everest Forms.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Everest Forms plugin for WordPress (versions <= 3.4.3) is vulnerable to unauthenticated PHP Object Injection due to improper use of the native PHP unserialize() function on form entry metadata. Attackers can submit malicious serialized objects through form fields, which are stored in the database and executed when an administrator views the submissions in the dashboard.

Vulnerable Code

// includes/admin/views/html-admin-page-entries-view.php

// The code retrieves entry meta and attempts to deserialize it without class restrictions:
$entry_meta = $wpdb->get_results( ... );

foreach ( $entry_meta as $meta_value ) {
    // ...
    $meta_val = unserialize( $meta_value->meta_value );
    // ...
}

Security Fix

--- a/includes/admin/views/html-admin-page-entries-view.php
+++ b/includes/admin/views/html-admin-page-entries-view.php
@@ -124,7 +124,7 @@
 																									if ( is_serialized( $meta_value->meta_value ) ) {
-																									$meta_val = unserialize( $meta_value->meta_value );
+																									$meta_val = unserialize( $meta_value->meta_value, array( 'allowed_classes' => false ) );
 																									if ( is_array( $meta_val ) ) {

Exploit Outline

1. Access a public page containing an Everest Forms form and extract the submission nonce from 'window.evf_frontend_params'. 2. Construct a PHP Object Injection payload using an available POP gadget chain. 3. Send an unauthenticated POST request to '/wp-admin/admin-ajax.php' with the 'action' set to 'everest_forms_submit_form' and the malicious payload in a form field parameter. 4. The payload is stored in the 'wp_evf_entrymeta' table as part of the submission metadata. 5. Trigger the payload by having an administrator visit the 'Entries' management page ('wp-admin/admin.php?page=evf-entries') in the WordPress backend, where the plugin insecurely deserializes the stored value.

Check if your site is affected.

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