ShortPixel Image Optimizer – Optimize Images, Convert WebP & AVIF <= 6.4.3 - Authenticated (Author+) PHP Object Injection
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:HTechnical Details
<=6.4.3Source Code
WordPress.org SVNThis 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:
dataoroptions. - 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)
- The plugin registers an AJAX handler:
add_action('wp_ajax_shortpixel_image_action', [...]). - The handler function retrieves user input from
$_POST['data']. - The input is decoded (e.g.,
base64_decode). - The plugin calls
unserialize($decoded_data)ormaybe_unserialize($decoded_data). - If
$decoded_datacontains 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.
- Identify Shortcode/Page: The Media Library (
upload.php) is the most reliable place for an Author to find ShortPixel nonces. - Access Page: Log in as an Author and navigate to
wp-admin/upload.php?mode=list. - Extract Nonce: The plugin localizes data via
wp_localize_script.- JS Variable:
shortPixelorSPIO. - Nonce Key:
nonceorshortPixelNonce. - Script execution:
browser_eval("window.shortPixel?.nonce")orbrowser_eval("window.SPIO?.nonce").
- JS Variable:
5. Test Data Setup
- Install Plugin: Install ShortPixel Image Optimizer version 6.4.3.
- Create User: Create a user with the
authorrole. - 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. - 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 OKwith JSON data, but the PHP magic methods will have executed on the backend during theunserializecall.
8. Verification Steps
- 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. - Database Check: Use
wp_clito check if any options or metadata were modified if the payload was designed to do so. - 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_actionis not the correct name, grep the source forwp_ajax_andunserializesimultaneously:grep -r "unserialize" . | grep "POST" - Metadata Exploitation: If the injection occurs via post metadata, use the
http_requesttool to update a post's metadata (if the plugin allows) and then trigger the optimization/viewing process that callsunserializeon 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 namedShortPixelBulkData.
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
@@ -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.