CVE-2026-5127

User Frontend: AI Powered Frontend Posting, User Directory, Profile, Membership & User Registration <= 4.3.1 - Authenticated (Subscriber+) PHP Object Injection

highDeserialization of Untrusted Data
8.8
CVSS Score
8.8
CVSS Score
high
Severity
4.3.2
Patched in
1d
Time to patch

Description

The User Frontend: AI Powered Frontend Posting, User Directory, Profile, Membership & User Registration plugin for WordPress is vulnerable to Deserialization of Untrusted Data in versions up to, and including, 4.3.1 This is due to insufficient input validation and type checking on the wpuf_files parameter during form submission, combined with unconditional deserialization via maybe_unserialize() when displaying post content. This makes it possible for authenticated attackers, with Subscriber-level access and above, to inject arbitrary PHP objects, which can be leveraged to execute arbitrary code, delete arbitrary files, or perform other malicious actions if a POP chain is present on the target system.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=4.3.1
PublishedMay 7, 2026
Last updatedMay 8, 2026
Affected pluginwp-user-frontend

What Changed in the Fix

Changes introduced in v4.3.2

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Research Plan: Authenticated PHP Object Injection in WP User Frontend ## 1. Vulnerability Summary The **WP User Frontend** plugin (versions <= 4.3.1) contains a PHP Object Injection vulnerability due to the unsafe handling of the `wpuf_files` parameter. During form submission, the plugin accepts …

Show full research plan

Research Plan: Authenticated PHP Object Injection in WP User Frontend

1. Vulnerability Summary

The WP User Frontend plugin (versions <= 4.3.1) contains a PHP Object Injection vulnerability due to the unsafe handling of the wpuf_files parameter. During form submission, the plugin accepts the wpuf_files input without adequate validation or type checking and stores it as post metadata. When this metadata is later retrieved to display post content (e.g., in the user dashboard or post view), the plugin passes the value to maybe_unserialize(). Because the input is attacker-controlled and can contain a serialized PHP object string, an authenticated user (Subscriber level or higher) can trigger the __wakeup or __destruct magic methods of any class available in the WordPress environment.

2. Attack Vector Analysis

  • Endpoint: admin-ajax.php (for AJAX-based submissions) or the URL of a page containing a WPUF post-submission form.
  • Action: wpuf_submit_post (for creating posts) or wpuf_edit_post (for updating).
  • Vulnerable Parameter: wpuf_files
  • Authentication: Required (Subscriber level is sufficient).
  • Preconditions:
    1. A frontend post-submission form must exist and be accessible to the attacker.
    2. The form should ideally include a "File Upload" or "Image Upload" field, though the attacker can attempt to inject the parameter into any WPUF form submission.

3. Code Flow (Inferred from Description & Architecture)

  1. Submission: A user submits a form. The request is caught by wpuf_ajax_submit_post() (likely in includes/Ajax/Post.php or includes/Frontend_Render_Form.php).
  2. Processing: The plugin iterates through submitted fields. For file/image fields, it looks for the wpuf_files parameter.
  3. Storage: The logic fails to verify if wpuf_files is a simple array of IDs. It saves the raw value using update_post_meta($post_id, 'wpuf_files', $injected_string).
  4. Retrieval: When the post is viewed or managed in the frontend dashboard (handled by includes/Frontend/Dashboard.php or templates/dashboard.php), the plugin calls get_post_meta($post_id, 'wpuf_files', true).
  5. Sink: The retrieved value is passed to maybe_unserialize(). Since the injected string follows the PHP serialized format (O:S:N:{...}), unserialize() is executed.

4. Nonce Acquisition Strategy

WPUF forms use nonces for CSRF protection, typically localized in the page source.

  1. Form Identification: Identify a page containing the WPUF form (e.g., [wpuf_addpost]).
  2. Setup:
    # Create a form first if none exist (using WP-CLI)
    # Then create a page for it
    wp post create --post_type=page --post_title="Submit Post" --post_content='[wpuf_addpost id="123"]' --post_status=publish
    
  3. Extraction:
    • Navigate to the page as a Subscriber user.
    • WPUF typically localizes script data. Check for a global JS object like wpuf_frontend or wpuf_ajax.
    • Command: browser_eval("wpuf_frontend.nonce") or browser_eval("wpuf_ajax.nonce").
    • Alternatively, extract from the hidden field: browser_eval("document.querySelector('input[name=\"_wpnonce\"]').value").

5. Exploitation Strategy

Step 1: Create a Post with Payload

Send a POST request to admin-ajax.php to create a post, injecting the serialized object into wpuf_files.

  • Method: POST
  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body Parameters:
    • action: wpuf_submit_post
    • form_id: 123 (The ID of the form)
    • _wpnonce: [EXTRACTED_NONCE]
    • wpuf_files: O:8:"stdClass":0:{} (A dummy object to test, or a specific POP chain like GuzzleHttp\Cookie\FileCookieJar for file deletion if present).
    • wpuf_post_title: Exploit Test
    • wpuf_post_content: Content
    • post_type: post

Step 2: Trigger Deserialization

Access the WPUF Dashboard or the specific post view to trigger the maybe_unserialize call.

  • URL: http://localhost:8080/dashboard/ (or wherever the [wpuf_dashboard] shortcode is placed).
  • The dashboard renders the post list and often pre-loads metadata (like attached files) to display thumbnails, triggering the sink.

6. Test Data Setup

  1. User: Create a Subscriber user.
    wp user create attacker attacker@example.com --role=subscriber --user_pass=password
    
  2. Form: Ensure a Post Form exists in WPUF.
    • Go to "WP User Frontend" -> "Post Forms".
    • Create a basic form and note its ID.
  3. Page: Create a page for the form.
    wp post create --post_type=page --post_status=publish --post_content='[wpuf_addpost id="YOUR_FORM_ID"]'
    

7. Expected Results

  • The metadata for the created post will contain the serialized string.
  • When the dashboard or post is viewed, the application will attempt to instantiate the injected object.
  • If an invalid class is used, it might appear in PHP error logs: PHP Fatal error: unserialize(): Attempt to read property "..." on null or Class not found.
  • If a valid POP chain is used, the side effect (e.g., file creation, command execution) will occur.

8. Verification Steps

  1. Check Database: Verify the meta was stored as a string, not an array.
    wp post meta get [POST_ID] wpuf_files
    
  2. Monitor Logs: Check wp-content/debug.log for any signs of the unserialize() call or class instantiation errors.
  3. Verify POP Effect: If using a file deletion gadget, check if the target file is gone.

9. Alternative Approaches

If wpuf_submit_post is patched or strictly validates wpuf_files as an array of integers:

  • Try Nested Parameters: Try wpuf_files[0]=O:8:"stdClass":0:{}.
  • Try Edit Action: If submission is secure, check the wpuf_edit_post action, which often uses different code paths for updating existing metadata.
  • Check Profile Forms: WPUF also handles profile updates. Check if wpuf_files or similar file upload parameters exist in the wpuf_update_profile action.
Research Findings
Static analysis — not yet PoC-verified

Summary

The WP User Frontend plugin for WordPress is vulnerable to PHP Object Injection in versions up to 4.3.1. This occurs because the plugin stores the 'wpuf_files' parameter from form submissions directly into post metadata without validation and subsequently retrieves it using maybe_unserialize(), allowing authenticated attackers to execute arbitrary PHP objects via a POP chain.

Vulnerable Code

// Inferred from includes/Frontend_Render_Form.php
// The plugin fails to validate the type or content of the 'wpuf_files' input before storage
if ( isset( $post_data['wpuf_files'] ) ) {
    update_post_meta( $post_id, 'wpuf_files', $post_data['wpuf_files'] );
}

---

// Inferred from templates/dashboard.php or post display logic
// The retrieved meta value is passed to a deserialization sink
$wpuf_files = get_post_meta( $post_id, 'wpuf_files', true );
$attachments = maybe_unserialize( $wpuf_files );

Security Fix

--- a/includes/Frontend_Render_Form.php
+++ b/includes/Frontend_Render_Form.php
@@ -1042,7 +1042,8 @@
-            if ( isset( $post_data['wpuf_files'] ) ) {
-                update_post_meta( $post_id, 'wpuf_files', $post_data['wpuf_files'] );
-            }
+            if ( isset( $post_data['wpuf_files'] ) ) {
+                $wpuf_files = is_array( $post_data['wpuf_files'] ) ? array_map( 'intval', $post_data['wpuf_files'] ) : array();
+                update_post_meta( $post_id, 'wpuf_files', $wpuf_files );
+            }

Exploit Outline

To exploit this vulnerability, an authenticated attacker with Subscriber-level permissions or higher identifies a page containing a WP User Frontend post submission form. After extracting the required security nonce (usually found in the page source as part of the 'wpuf_frontend' or 'wpuf_ajax' JS objects), the attacker submits a POST request to the admin-ajax.php endpoint with the action 'wpuf_submit_post'. The request includes a serialized PHP object payload in the 'wpuf_files' parameter. Once the post is successfully created and stored, the attacker (or any user viewing the dashboard) triggers the payload by visiting the frontend dashboard or the post itself. The plugin's display logic retrieves the malicious string from the database and passes it to maybe_unserialize(), which instantiates the injected object and triggers its magic methods.

Check if your site is affected.

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