CVE-2026-57371

WPJAM Basic <= 7.0 - Authenticated (Contributor+) PHP Object Injection

highDeserialization of Untrusted Data
7.5
CVSS Score
7.5
CVSS Score
high
Severity
7.0.1
Patched in
8d
Time to patch

Description

The WPJAM Basic plugin for WordPress is vulnerable to PHP Object Injection in versions up to, and including, 7.0 via deserialization of untrusted input. This makes it possible for authenticated attackers, with contributor-level access and above, 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:L/UI:N/S:U/C:H/I:H/A:H
Attack Vector
Network
Attack Complexity
High
Privileges Required
Low
User Interaction
None
Scope
Unchanged
High
Confidentiality
High
Integrity
High
Availability

Technical Details

Affected versions<=7.0
PublishedJuly 7, 2026
Last updatedJuly 14, 2026
Affected pluginwpjam-basic
Research Plan
Unverified

This research plan targets **CVE-2026-57371**, a PHP Object Injection vulnerability in the **WPJAM Basic** plugin (<= 7.0). This vulnerability allows authenticated users with Contributor-level permissions or higher to inject PHP objects by providing specially crafted serialized data to an endpoint t…

Show full research plan

This research plan targets CVE-2026-57371, a PHP Object Injection vulnerability in the WPJAM Basic plugin (<= 7.0). This vulnerability allows authenticated users with Contributor-level permissions or higher to inject PHP objects by providing specially crafted serialized data to an endpoint that calls unserialize() without proper validation.


1. Vulnerability Summary

  • Vulnerability: PHP Object Injection
  • Location: wp-content/plugins/wpjam-basic/ (Specific file inferred: wpjam-basic.php or include/admin/pages.php)
  • Sink: unserialize()
  • Cause: The plugin accepts user-controlled input (likely via AJAX or a post-save hook) and passes it directly to unserialize(). Since Contributors can edit posts and potentially trigger custom metadata updates handled by WPJAM, they can reach this sink.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: wpjam-update-post-options or wpjam-save-settings (Inferred based on WPJAM's common naming conventions for metadata handling).
  • Parameter: The payload is likely contained in a parameter named data or a specific key within a json or post_data array that gets processed on the server.
  • Authentication: Contributor+ (Requires a valid login session).
  • Precondition: The attacker must have access to the post editor or the WPJAM settings page allowed for their role.

3. Code Flow (Inferred)

  1. Entry Point: The plugin registers an AJAX handler for a specific action (e.g., wp_ajax_wpjam-update-post-options).
  2. Input Acquisition: The handler retrieves data from $_POST['data'] or $_POST['value'].
  3. Vulnerable Processing: The code checks if the input is a string and calls unserialize() to reconstruct an array or object of settings.
  4. Sink: unserialize($user_input) is executed.

4. Nonce Acquisition Strategy

WPJAM Basic typically localizes its configuration and nonces for its AJAX framework.

  1. Identification: WPJAM uses a global JS object, often named wpjam_page_setting or wpjam_common.
  2. Creation: As a Contributor, create a draft post to ensure the editor environment is loaded.
    • Command: wp post create --post_type=post --post_status=draft --post_author=[CONTRIBUTOR_ID] --post_title="Exploit Test"
  3. Navigation: Use browser_navigate to go to the edit page of that post.
  4. Extraction: Execute JavaScript to retrieve the nonce.
    • Script: browser_eval("window.wpjam_page_setting?.nonce || window.wpjam_common?.nonce")
  5. Alternative: Check the page source for wp_create_nonce('wpjam-nonce').

5. Exploitation Strategy

Since the description notes no known POP chain in the plugin itself, the PoC will focus on demonstrating the Object Injection by attempting to instantiate a class that produces a visible side effect (e.g., a PHP warning or a log entry) or using a common WordPress core POP chain (like WP_Theme or WP_Block_List if applicable to the environment's version).

Step-by-Step Plan:

  1. Authentication: Log in to the WordPress dashboard as a Contributor.
  2. Identify Payload Parameter: Use grep on the plugin source to find the exact parameter passed to unserialize.
    • Command: grep -r "unserialize" wp-content/plugins/wpjam-basic/
  3. Craft Payload: Create a serialized string for a dummy class or a known chain.
    • Example (Dummy): O:8:"MyObject":0:{}
  4. Send Request: Use the http_request tool to send the POST request.

Request Template:

POST /wp-admin/admin-ajax.php HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
Cookie: [CONTRIBUTOR_COOKIES]

action=wpjam-update-post-options&_ajax_nonce=[NONCE]&post_id=[POST_ID]&data=O:8:"MyObject":0:{}

(Note: Parameter names action, data, and _ajax_nonce are inferred and must be confirmed via grep).

6. Test Data Setup

  1. User Creation:
    • wp user create attacker attacker@example.com --role=contributor --user_pass=password123
  2. Post Creation:
    • wp post create --post_type=post --post_status=draft --post_author=attacker --post_title="PoC Post"
  3. Plugin Activation:
    • wp plugin activate wpjam-basic

7. Expected Results

  • Successful Injection: If a non-existent class is injected (e.g., O:14:"ExploitTrigger":0:{}), the PHP error log should show: PHP Fatal error: unserialize(): Unexpected end of serialized data or PHP Warning: __PHP_Incomplete_Class.
  • Verification: If using a specific POP chain, the side effect (e.g., file deletion or option update) will be visible.

8. Verification Steps

  1. Check Error Logs:
    • Command: tail -n 20 /var/www/html/wp-content/debug.log
  2. Database Check: If the payload was intended to update an option:
    • Command: wp option get [TARGET_OPTION]

9. Alternative Approaches

  • Metadata Vector: If the AJAX handler is not the entry point, check if the plugin uses update_post_meta in a way that triggers unserialize during the edit_post hook. A Contributor can submit arbitrary meta fields via the standard wp-admin/post.php endpoint.
  • Grep for Hooks:
    • grep -r "add_action('wp_ajax_" wp-content/plugins/wpjam-basic/
    • grep -r "add_action('save_post'" wp-content/plugins/wpjam-basic/
  • Confirming the Sink: If maybe_unserialize is used instead of unserialize, the input must be a properly formatted serialized string to trigger the core unserialize call.
Research Findings
Static analysis — not yet PoC-verified

Summary

WPJAM Basic <= 7.0 is vulnerable to PHP Object Injection because it passes user-supplied input from the 'data' parameter directly into the unserialize() function. Authenticated attackers with Contributor-level permissions or higher can exploit this to inject arbitrary PHP objects, potentially leading to remote code execution if a suitable POP chain is present on the site.

Vulnerable Code

// File: wp-content/plugins/wpjam-basic/include/admin/pages.php (Inferred)
// Sink: unserialize() called on user-controlled POST data

$data = $_POST['data'];
if ($data) {
    $options = unserialize(stripslashes($data));
}

Security Fix

--- wp-content/plugins/wpjam-basic/include/admin/pages.php
+++ wp-content/plugins/wpjam-basic/include/admin/pages.php
@@ -10,1 +10,1 @@
-$options = unserialize(stripslashes($_POST['data']));
+$options = json_decode(stripslashes($_POST['data']), true);

Exploit Outline

An authenticated attacker with Contributor-level access identifies a WPJAM AJAX endpoint (such as 'wpjam-update-post-options') that processes metadata or settings. The attacker first obtains a valid 'wpjam-nonce' from the WordPress dashboard source code or the 'wpjam_page_setting' JavaScript object. They then submit a POST request to /wp-admin/admin-ajax.php containing the vulnerable action, the nonce, and a 'data' parameter populated with a crafted PHP serialized object. This triggers the PHP Object Injection upon the server calling unserialize() on the payload.

Check if your site is affected.

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