CVE-2026-5821

Image Optimizer <= 1.7.4 - Authenticated (Author+) Arbitrary File Deletion via Post Meta Field Injection

highExternal Control of File Name or Path
8.1
CVSS Score
8.1
CVSS Score
high
Severity
1.7.5
Patched in
1d
Time to patch

Description

The Image Optimizer plugin for WordPress is vulnerable to arbitrary file deletion in versions up to and including 1.7.4. This is due to insufficient path validation in the Image_Backup::remove() function where backup file paths stored in post meta are used directly in file deletion operations without verifying they are within the uploads directory. The plugin stores backup file paths in the image_optimizer_metadata post meta field and trusts these paths completely when deleting backups on the delete_attachment hook. An authenticated attacker with Author-level access can edit the image_optimizer_metadata post meta on their own attachments via WordPress's Custom Fields interface, injecting arbitrary absolute file paths into the backups array. When the attacker subsequently deletes the attachment, the plugin calls File_System::delete() on each path without validation. This makes it possible for authenticated attackers, with Author-level access and above, to delete arbitrary files on the server within the web server's filesystem permissions, potentially leading to denial of service, data loss, or security degradation.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=1.7.4
PublishedJuly 1, 2026
Last updatedJuly 2, 2026
Affected pluginimage-optimization

What Changed in the Fix

Changes introduced in v1.7.5

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan - CVE-2026-5821 ## 1. Vulnerability Summary The **Image Optimization – Compress Images and Convert to WebP or AVIF** plugin (versions <= 1.7.4) is vulnerable to authenticated arbitrary file deletion. The vulnerability exists in the `Image_Backup::remove()` function, whi…

Show full research plan

Exploitation Research Plan - CVE-2026-5821

1. Vulnerability Summary

The Image Optimization – Compress Images and Convert to WebP or AVIF plugin (versions <= 1.7.4) is vulnerable to authenticated arbitrary file deletion. The vulnerability exists in the Image_Backup::remove() function, which is hooked into WordPress's delete_attachment action.

The plugin stores paths to backup files in the image_optimizer_metadata post meta field (specifically within a backups array). When an attachment is deleted, the plugin retrieves this meta, iterates through the backups array, and calls File_System::delete() on each path. Because the plugin fails to validate that these paths are restricted to the expected uploads directory, an attacker with Author-level permissions can modify the post meta of an attachment they own to include arbitrary absolute file paths. Deleting the attachment then triggers the deletion of those files.

2. Attack Vector Analysis

  • Endpoint: wp-admin/post.php (for both meta update and attachment deletion).
  • Vulnerable Hook: delete_attachment.
  • Vulnerable Sink: File_System::delete($path).
  • Payload Parameter: The metavalue for the image_optimizer_metadata key.
  • Preconditions:
    • Attacker must have at least Author level access (to upload and manage their own attachments).
    • The target file must be writable/deletable by the web server user (e.g., www-data).
  • Required Knowledge: The absolute path of the target file on the server.

3. Code Flow

  1. Entry Point: A user with delete_posts capability (Author+) deletes an attachment.
  2. Hook Trigger: WordPress fires the delete_attachment hook.
  3. Plugin Execution: The plugin's registered callback Image_Backup::remove($post_id) (inferred) is executed.
  4. Data Retrieval: The function calls get_post_meta($post_id, 'image_optimizer_metadata', true).
  5. Payload Processing: The code accesses the backups key from the returned meta array/object:
    // Inferred logic based on description
    $meta = get_post_meta($post_id, 'image_optimizer_metadata', true);
    if (isset($meta['backups']) && is_array($meta['backups'])) {
        foreach ($meta['backups'] as $backup_path) {
            File_System::delete($backup_path); // SINK
        }
    }
    
  6. Sink Execution: File_System::delete() executes unlink() or a similar filesystem operation on the unvalidated $backup_path.

4. Nonce Acquisition Strategy

Since the attacker is an Author, they have access to the WordPress Admin dashboard. Nonces are required for updating post meta and deleting the post.

  1. Meta Update Nonce: Found in the attachment edit page (wp-admin/post.php?post=[ID]&action=edit). The nonce for adding/updating custom fields is typically named _wpnonce in the main edit form or specifically addmeta for the custom fields AJAX.
  2. Deletion Nonce: Found in the attachment edit page or the Media Library. The action is delete-post-[ID], and the nonce is usually passed as _wpnonce in the deletion URL: post.php?action=delete&post=[ID]&_wpnonce=[NONCE].

Strategy:

  • Use browser_navigate to go to the attachment edit page.
  • Use browser_eval to extract the _wpnonce from the form.
  • Use browser_eval to extract the _wpnonce from the "Delete Permanently" link.

5. Exploitation Strategy

The goal is to delete a sensitive file (e.g., wp-config.php or a test file).

  1. Step 1: Setup
    • Create an Author user.
    • Create a dummy file at /tmp/pwned.txt to safely demonstrate deletion.
  2. Step 2: Login and Upload
    • Login as the Author.
    • Upload a legitimate image to get an attachment ID ($ATTACH_ID).
  3. Step 3: Inject Payload into Post Meta
    • Navigate to the edit page for $ATTACH_ID.
    • Use the Custom Fields interface to add or update the image_optimizer_metadata key.
    • Payload (Serialized PHP): a:1:{s:7:"backups";a:1:{i:0;s:14:"/tmp/pwned.txt";}}
    • Note: WordPress get_post_meta with $single=true will automatically maybe_unserialize this string into the array the plugin expects.
  4. Step 4: Trigger Deletion
    • Submit a request to post.php?action=delete&post=$ATTACH_ID&_wpnonce=$DEL_NONCE.
  5. Step 5: Verify
    • Check if /tmp/pwned.txt still exists.

6. Test Data Setup

  • Target File: /tmp/pwned.txt (ensure web server has permission to delete).
  • User: Username: attacker, Password: password123, Role: author.
  • Media: A standard image file (e.g., test.png) uploaded by attacker.

7. Expected Results

  • The request to action=delete returns a 302 redirect to the Media Library.
  • The attachment is removed from the database (wp_posts table).
  • The file /tmp/pwned.txt is successfully deleted from the filesystem.

8. Verification Steps

  1. Via WP-CLI:
    # Check if attachment is gone
    wp post exists [ID]
    # Check if file is gone
    ls /tmp/pwned.txt
    
  2. Check Database:
    wp db query "SELECT * FROM wp_postmeta WHERE post_id = [ID] AND meta_key = 'image_optimizer_metadata'"
    

9. Alternative Approaches

If the Custom Fields UI is disabled or hidden:

  • REST API: Check if the Author can update meta via POST /wp-json/wp/v2/media/[ID]. This requires the image_optimizer_metadata to be registered with show_in_rest => true.
  • Direct AJAX: Attempt to use the add-meta action in admin-ajax.php which is the backend for the Custom Fields UI:
    POST /wp-admin/admin-ajax.php
    Content-Type: application/x-www-form-urlencoded
    
    action=add-meta&_ajax_nonce-add-meta=[NONCE]&post_id=[ID]&metakeyinput=image_optimizer_metadata&metavalue=[SERIALIZED_PAYLOAD]
    
Research Findings
Static analysis — not yet PoC-verified

Summary

The Image Optimizer plugin for WordPress is vulnerable to arbitrary file deletion because it fails to validate file paths retrieved from post meta before using them in a deletion operation. Authenticated attackers with Author-level permissions can modify an attachment's metadata to include absolute server paths, which the plugin subsequently deletes when the attachment is removed.

Vulnerable Code

// Inferred from vulnerability description
// Path: includes/image-backup.php

public function remove( $post_id ) {
    $meta = get_post_meta( $post_id, 'image_optimizer_metadata', true );

    if ( ! empty( $meta['backups'] ) && is_array( $meta['backups'] ) ) {
        foreach ( $meta['backups'] as $file_path ) {
            // Vulnerable: $file_path is taken directly from post meta without path validation
            File_System::delete( $file_path );
        }
    }
}

Security Fix

--- includes/image-backup.php
+++ includes/image-backup.php
@@ -4,7 +4,11 @@
     $meta = get_post_meta( $post_id, 'image_optimizer_metadata', true );
     
     if ( ! empty( $meta['backups'] ) && is_array( $meta['backups'] ) ) {
+        $upload_dir = wp_upload_dir();
         foreach ( $meta['backups'] as $file_path ) {
-            File_System::delete( $file_path );
+            // Validate that the file path is located within the WordPress uploads directory
+            if ( strpos( wp_normalize_path( $file_path ), wp_normalize_path( $upload_dir['basedir'] ) ) === 0 ) {
+                File_System::delete( $file_path );
+            }
         }
     }

Exploit Outline

1. Authenticate as an Author or higher and upload an image to the media library to generate a target attachment ID. 2. Access the attachment's edit page in the WordPress admin dashboard to view the Custom Fields interface. 3. Modify or add the 'image_optimizer_metadata' meta key, injecting a serialized PHP array containing a 'backups' list that includes the absolute system path of the target file to be deleted (e.g., '/var/www/html/wp-config.php'). 4. Send a request to 'wp-admin/post.php?action=delete' for the attachment ID, including the necessary security nonces obtained from the admin UI. 5. The plugin's hook for the 'delete_attachment' action will trigger, causing the 'Image_Backup::remove' function to process the malicious meta and delete the targeted file.

Check if your site is affected.

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