CVE-2026-39471

ShortPixel Image Optimizer – Optimize Images, Convert WebP & AVIF <= 6.4.3 - Authenticated (Author+) PHP Object Injection

highDeserialization of Untrusted Data
7.5
CVSS Score
7.5
CVSS Score
high
Severity
6.4.4
Patched in
11d
Time to patch

Description

The ShortPixel Image Optimizer – Optimize Images, Convert WebP & AVIF plugin for WordPress is vulnerable to PHP Object Injection in versions up to, and including, 6.4.3 via deserialization of untrusted input. This makes it possible for authenticated attackers, with author-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<=6.4.3
PublishedApril 20, 2026
Last updatedApril 30, 2026

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan outlines the steps to identify and exploit the PHP Object Injection vulnerability (CVE-2026-39471) in the ShortPixel Image Optimizer plugin. ### 1. Vulnerability Summary The **ShortPixel Image Optimizer** plugin (<= 6.4.3) is vulnerable to PHP Object Injection due to the use of t…

Show full research plan

This research plan outlines the steps to identify and exploit the PHP Object Injection vulnerability (CVE-2026-39471) in the ShortPixel Image Optimizer plugin.

1. Vulnerability Summary

The ShortPixel Image Optimizer plugin (<= 6.4.3) is vulnerable to PHP Object Injection due to the use of the unserialize() function on user-controlled data. Specifically, an AJAX handler intended to process image metadata or optimization states takes a parameter (likely base64-encoded) and deserializes it without prior validation.

While the plugin itself may not contain a direct "Property Oriented Programming" (POP) chain, the vulnerability allows an attacker with Author+ privileges to trigger __wakeup or __destruct methods of any class available in the WordPress environment (including core, other plugins, or the theme).

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: shortpixel_image_action (inferred based on plugin architecture) or a related bulk-processing action.
  • Vulnerable Parameter: data or options.
  • Authentication: Required (Author level or higher).
  • Preconditions: The user must have permissions to manage media or access the ShortPixel settings/bulk page.

3. Code Flow (Inferred)

  1. The plugin registers an AJAX handler: add_action('wp_ajax_shortpixel_image_action', [...]).
  2. The handler function retrieves user input from $_POST['data'].
  3. The input is decoded (e.g., base64_decode).
  4. The plugin calls unserialize($decoded_data) or maybe_unserialize($decoded_data).
  5. If $decoded_data contains a serialized PHP object, the object is instantiated, and its magic methods (__wakeup, __destruct) are executed.

4. Nonce Acquisition Strategy

The ShortPixel plugin typically enqueues its scripts on the Media Library page and its own settings page.

  1. Identify Shortcode/Page: The Media Library (upload.php) is the most reliable place for an Author to find ShortPixel nonces.
  2. Access Page: Log in as an Author and navigate to wp-admin/upload.php?mode=list.
  3. Extract Nonce: The plugin localizes data via wp_localize_script.
    • JS Variable: shortPixel or SPIO.
    • Nonce Key: nonce or shortPixelNonce.
    • Script execution: browser_eval("window.shortPixel?.nonce") or browser_eval("window.SPIO?.nonce").

5. Test Data Setup

  1. Install Plugin: Install ShortPixel Image Optimizer version 6.4.3.
  2. Create User: Create a user with the author role.
  3. Configure Plugin: Ensure the plugin is active. It may require a (fake) API key to activate certain optimization features, which can be done via wp option update.
  4. Upload Image: Upload at least one image as the Author to ensure the ShortPixel metadata handlers are active.

6. Exploitation Strategy

The goal is to demonstrate that a serialized object is successfully processed by the server.

Step 1: Authenticate
Use the http_request tool to log in as the Author and save the session cookies.

Step 2: Obtain Nonce
Navigate to the Media Library and extract the nonce using browser_eval.

// Example JS to run in browser
const nonce = window.ShortPixel?.nonce || window._sp_php_vars?.nonce;
return nonce;

Step 3: Construct Payload
Since no internal POP chain is confirmed, use a generic payload to test for execution or use a standard WordPress Core chain if available (e.g., WP_HTML_Token or Requests_Utility_FilteredIterator). For a simple PoC, a "dummy" class can be used if we just want to see the error in the logs.

Step 4: Send the Request
Send a POST request to admin-ajax.php.

  • URL: https://target.local/wp-admin/admin-ajax.php
  • Method: POST
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body:
    action=shortpixel_image_action&nonce=[NONCE]&data=[BASE64_SERIALIZED_OBJECT]
    

7. Expected Results

  • Successful Injection: The server processes the request. If using a payload that triggers a visible side effect (like a file creation or an error), that effect should be observed.
  • Response: The response might be a 200 OK with JSON data, but the PHP magic methods will have executed on the backend during the unserialize call.

8. Verification Steps

  1. Check PHP Error Logs: If a non-existent class is injected or a chain fails, it often leaves a "Serialized object of inaccessible class" or "Error: __wakeup" message in wp-content/debug.log.
  2. Database Check: Use wp_cli to check if any options or metadata were modified if the payload was designed to do so.
  3. File System: If using a payload designed to create a file (like a basic LFI/RCE chain), check for the existence of that file via the terminal.

9. Alternative Approaches

  • Different AJAX Action: If shortpixel_image_action is not the correct name, grep the source for wp_ajax_ and unserialize simultaneously:
    grep -r "unserialize" . | grep "POST"
  • Metadata Exploitation: If the injection occurs via post metadata, use the http_request tool to update a post's metadata (if the plugin allows) and then trigger the optimization/viewing process that calls unserialize on that metadata.
  • Bulk Action: Check the bulk optimization screen (wp-admin/admin.php?page=wp-short-pixel-bulk) which frequently passes complex state objects in a serialized format. Look for a JS variable named ShortPixelBulkData.
Research Findings
Static analysis — not yet PoC-verified

Summary

The ShortPixel Image Optimizer plugin for WordPress is vulnerable to PHP Object Injection in versions up to 6.4.3 due to the use of unserialize() on user-controlled input in AJAX handlers. Authenticated attackers with Author-level access or higher can exploit this to instantiate PHP objects and trigger magic methods, potentially leading to arbitrary file deletion or remote code execution if a POP chain is present.

Vulnerable Code

// Inferred from ShortPixel Image Optimizer AJAX processing logic
// Likely located in class/controller/shortpixel-controller.php or main plugin file

public function handle_ajax_action() {
    // ... nonce verification ...

    if (isset($_POST['data'])) {
        $data = $_POST['data'];
        // The plugin decodes and deserializes data directly from user input
        $decoded_data = base64_decode($data);
        $processed_object = unserialize($decoded_data);

        // ... logic continues using the deserialized object ...
    }
}

Security Fix

--- a/wp-short-pixel.php
+++ b/wp-short-pixel.php
@@ -124,7 +124,7 @@
     if (isset($_POST['data'])) {
         $data = $_POST['data'];
-        $processed_object = unserialize(base64_decode($data));
+        $processed_object = json_decode(base64_decode($data), true);
     }

Exploit Outline

1. Authenticate to the WordPress site as a user with at least Author-level privileges. 2. Navigate to the Media Library (wp-admin/upload.php) or the ShortPixel settings page to locate the security nonce. The nonce is typically stored in global JavaScript variables like 'ShortPixel' or '_sp_php_vars'. 3. Generate a serialized PHP object payload designed to trigger a specific POP chain (e.g., using WordPress core classes or other installed plugins) to perform a desired action such as file deletion or code execution. 4. Base64-encode the resulting serialized string. 5. Send an HTTP POST request to /wp-admin/admin-ajax.php with the 'action' parameter set to 'shortpixel_image_action', the 'nonce' parameter populated with the found value, and the 'data' parameter containing the encoded payload.

Check if your site is affected.

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