CVE-2026-32484

weForms – Easy Drag & Drop Contact Form Builder For WordPress <= 1.6.26 - Unauthenticated PHP Object Injection

highDeserialization of Untrusted Data
8.1
CVSS Score
8.1
CVSS Score
high
Severity
1.6.27
Patched in
11d
Time to patch

Description

The weForms – Easy Drag & Drop Contact Form Builder For WordPress plugin for WordPress is vulnerable to PHP Object Injection in versions up to, and including, 1.6.26 via deserialization of untrusted input. This makes it possible for unauthenticated attackers to inject a PHP Object. No known POP chain is present in the vulnerable software. If a POP chain is present via an additional plugin or theme installed on the target system, it could allow the attacker to delete arbitrary files, retrieve sensitive data, or execute code.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=1.6.26
PublishedMarch 23, 2026
Last updatedApril 2, 2026
Affected pluginweforms

What Changed in the Fix

Changes introduced in v1.6.27

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan - CVE-2026-32484 (weForms Object Injection) ## 1. Vulnerability Summary The **weForms** plugin (<= 1.6.26) is vulnerable to **Unauthenticated PHP Object Injection**. The vulnerability exists because the plugin's entry-handling logic retrieves submitted form data from th…

Show full research plan

Exploitation Research Plan - CVE-2026-32484 (weForms Object Injection)

1. Vulnerability Summary

The weForms plugin (<= 1.6.26) is vulnerable to Unauthenticated PHP Object Injection. The vulnerability exists because the plugin's entry-handling logic retrieves submitted form data from the database and passes it directly to unserialize() or maybe_unserialize() when instantiating a WeForms_Form_Entry object. Since an unauthenticated user can submit form entries, they can inject a serialized PHP object payload into a field that the plugin later deserializes.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: weforms_frontend_submit (registered via wp_ajax_nopriv_weforms_frontend_submit in includes/class-ajax.php)
  • Vulnerable Parameter: Within the form_data POST parameter, any field name corresponding to a multiple_product or image_upload field type.
  • Authentication: None required (Unauthenticated).
  • Preconditions: A published form must exist containing at least one field of type multiple_product, image_upload, or file_upload.

3. Code Flow

  1. Entry Point: WeForms_Ajax::handle_frontend_submission() is called via AJAX.
  2. Processing: The function parses `$_
Research Findings
Static analysis — not yet PoC-verified

Summary

The weForms plugin is vulnerable to Unauthenticated PHP Object Injection because it uses unserialize() and maybe_unserialize() on user-controllable form entry data stored in the database. An attacker can submit a malicious serialized PHP object through specific form fields, which is later deserialized when an administrator views the entry or when the system processes the entry data.

Vulnerable Code

// includes/class-form-entry.php

                    } elseif ( in_array( $field['type'], [ 'image_upload', 'file_upload' ] ) ) {
                        $file_field = '';
                        $value      = maybe_unserialize( $value );

---

// includes/class-form-entry.php line 199

                    } elseif ( $field['type'] == 'multiple_product' ) {
                        $field_value = unserialize( $value );

---

// includes/class-ajax.php line 523

        $payment        = $entry->get_payment_data();

        if ( isset( $payment->payment_data ) && is_serialized( $payment->payment_data ) ) {
            $payment->payment_data = unserialize( $payment->payment_data );
        }

---

// includes/functions.php line 1251

function weforms_get_pain_text( $value ) {
    if ( is_serialized( $value ) ) {
        $value = unserialize( $value );
    }

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/weforms/1.6.26/includes/admin/class-privacy.php /home/deploy/wp-safety.org/data/plugin-versions/weforms/1.6.27/includes/admin/class-privacy.php
--- /home/deploy/wp-safety.org/data/plugin-versions/weforms/1.6.26/includes/admin/class-privacy.php	2024-03-20 20:17:32.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/weforms/1.6.27/includes/admin/class-privacy.php	2026-02-09 15:54:44.000000000 +0000
@@ -218,7 +218,10 @@
     }
 
     public static function process_payment_data( $payment_data ) {
-        $field_value = unserialize( $payment_data->payment_data );
+        // Security fix: Prevent PHP Object Injection by restricting allowed classes
+        $field_value = is_serialized( $payment_data->payment_data )
+            ? @unserialize( $payment_data->payment_data, [ 'allowed_classes' => false ] )
+            : $payment_data->payment_data;
 
         $serialized_value = [];
         $transaction_data = [];
diff -ru /home/deploy/wp-safety.org/data/plugin-versions/weforms/1.6.26/includes/api/class-weforms-forms-controller.php /home/deploy/wp-safety.org/data/plugin-versions/weforms/1.6.27/includes/api/class-weforms-forms-controller.php
--- /home/deploy/wp-safety.org/data/plugin-versions/weforms/1.6.26/includes/api/class-weforms-forms-controller.php	2020-10-20 13:26:26.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/weforms/1.6.27/includes/api/class-weforms-forms-controller.php	2026-02-09 15:54:44.000000000 +0000
@@ -1548,7 +1548,8 @@
         $payment       = $entry->get_payment_data();
 
         if ( isset( $payment->payment_data ) && is_serialized( $payment->payment_data ) ) {
-            $payment->payment_data = unserialize( $payment->payment_data );
+            // Security fix: Prevent PHP Object Injection by restricting allowed classes
+            $payment->payment_data = @unserialize( $payment->payment_data, [ 'allowed_classes' => false ] );
         }
 
         $has_empty          = false;
diff -ru /home/deploy/wp-safety.org/data/plugin-versions/weforms/1.6.26/includes/class-ajax.php /home/deploy/wp-safety.org/data/plugin-versions/weforms/1.6.27/includes/class-ajax.php
--- /home/deploy/wp-safety.org/data/plugin-versions/weforms/1.6.26/includes/class-ajax.php	2024-02-01 20:47:56.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/weforms/1.6.27/includes/class-ajax.php	2026-02-09 15:54:44.000000000 +0000
@@ -520,7 +520,8 @@
         $payment        = $entry->get_payment_data();
 
         if ( isset( $payment->payment_data ) && is_serialized( $payment->payment_data ) ) {
-            $payment->payment_data = unserialize( $payment->payment_data );
+            // Security fix: Prevent PHP Object Injection by restricting allowed classes
+            $payment->payment_data = @unserialize( $payment->payment_data, [ 'allowed_classes' => false ] );
         }
 
         if ( false === $fields ) {
diff -ru /home/deploy/wp-safety.org/data/plugin-versions/weforms/1.6.26/includes/class-form-entry.php /home/deploy/wp-safety.org/data/plugin-versions/weforms/1.6.27/includes/class-form-entry.php
--- /home/deploy/wp-safety.org/data/plugin-versions/weforms/1.6.26/includes/class-form-entry.php	2024-03-20 20:17:32.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/weforms/1.6.27/includes/class-form-entry.php	2026-02-09 15:54:44.000000000 +0000
@@ -170,7 +170,10 @@
                         }
                     } elseif ( in_array( $field['type'], [ 'image_upload', 'file_upload' ] ) ) {
                         $file_field = '';
-                        $value      = maybe_unserialize( $value );
+                        // Security fix: Prevent PHP Object Injection by restricting allowed classes
+                        $value      = is_serialized( $value )
+                            ? @unserialize( $value, [ 'allowed_classes' => false ] )
+                            : $value;
 
                         if ( is_array( $value ) && $value ) {
                             foreach ( $value as $attachment_id ) {
@@ -196,7 +199,10 @@
                             'long'    => trim( $long ),
                         ];
                     } elseif ( $field['type'] == 'multiple_product' ) {
-                        $field_value = unserialize( $value );
+                        // Security fix: Prevent PHP Object Injection by restricting allowed classes
+                        $field_value = is_serialized( $value )
+                            ? @unserialize( $value, [ 'allowed_classes' => false ] )
+                            : $value;
 
                         $serialized_value = [];
 
@@ -218,7 +224,10 @@
                             $value = implode( '<br> <br> ', $serialized_value );
                         }
                     } elseif ( $field['type'] == 'checkbox_grid' ) {
-                        $entry_value = unserialize( $value );
+                        // Security fix: Prevent PHP Object Injection by restricting allowed classes
+                        $entry_value = is_serialized( $value )
+                            ? @unserialize( $value, [ 'allowed_classes' => false ] )
+                            : $value;
 
                         if ( $entry_value ) {
                             $return = '';
@@ -281,7 +290,10 @@
                             $value = $return;
                         }
                     } elseif ( $field['type'] == 'multiple_choice_grid' ) {
-                        $entry_value = unserialize( $value );
+                        // Security fix: Prevent PHP Object Injection by restricting allowed classes
+                        $entry_value = is_serialized( $value )
+                            ? @unserialize( $value, [ 'allowed_classes' => false ] )
+                            : $value;
 
                         if ( $entry_value ) {
                             $return = '';
@@ -344,7 +356,10 @@
                             $value = $return;
                         }
                     } elseif ( $field['type'] == 'address_field' || is_serialized( $value ) ) {
-                        $field_value = unserialize( $value );
+                        // Security fix: Prevent PHP Object Injection by restricting allowed classes
+                        $field_value = is_serialized( $value )
+                            ? @unserialize( $value, [ 'allowed_classes' => false ] )
+                            : $value;
 
                         $serialized_value = [];
 
@@ -1248,14 +1248,15 @@
  * @return string
  **/
 function weforms_get_pain_text( $value ) {
-    if ( is_serialized( $value ) ) {
-        $value = unserialize( $value );
-    }
+    // Security fix: Removed unsafe unserialize() call to prevent PHP Object Injection.
+    // WordPress's get_metadata() already handles deserialization safely.
+    // Any serialized strings at this point should be treated as untrusted user input.
 
     if ( is_array( $value ) ) {
         $string_value = [];
         foreach ( $value as $key => $single_value ) {
-            if ( is_array( $single_value ) || is_serialized( $single_value ) ) {
+            // Only recursively process arrays, not serialized strings
+            if ( is_array( $single_value ) ) {
                 $single_value = weforms_get_pain_text( $single_value );
             }

Exploit Outline

1. Identify a published weForms form that contains at least one complex field type that results in database serialization (e.g., File Upload, Multiple Products, Checkbox Grid, or Address field). 2. Construct a malicious serialized PHP object payload designed to trigger a POP chain (if one exists in the environment's themes or other plugins). 3. Submit the form as an unauthenticated user by sending a POST request to `wp-admin/admin-ajax.php` with the action `weforms_frontend_submit`. 4. In the `form_data` payload, map the malicious serialized string to the field name corresponding to the vulnerable field type. 5. Wait for an administrator to view the form entries or trigger a system process (like an export or privacy data request) that forces the backend to instantiate a `WeForms_Form_Entry` object, which will trigger the unsafe `unserialize()` call.

Check if your site is affected.

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