[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fWtpxTfwZK-Yti_ZQtAk76W3A_LAYA0lA9FrZAeH9yfo":3},{"id":4,"url_slug":5,"title":6,"description":7,"plugin_slug":8,"theme_slug":9,"affected_versions":10,"patched_in_version":11,"severity":12,"cvss_score":13,"cvss_vector":14,"vuln_type":15,"published_date":16,"updated_date":17,"references":18,"days_to_patch":20,"patch_diff_files":21,"patch_trac_url":9,"research_status":30,"research_verified":31,"research_rounds_completed":32,"research_plan":33,"research_summary":34,"research_vulnerable_code":35,"research_fix_diff":36,"research_exploit_outline":37,"research_model_used":38,"research_started_at":39,"research_completed_at":40,"research_error":9,"poc_status":9,"poc_video_id":9,"poc_summary":9,"poc_steps":9,"poc_tested_at":9,"poc_wp_version":9,"poc_php_version":9,"poc_playwright_script":9,"poc_exploit_code":9,"poc_has_trace":31,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":31,"source_links":41},"CVE-2026-5821","image-optimizer-authenticated-author-arbitrary-file-deletion-via-post-meta-field-injection","Image Optimizer \u003C= 1.7.4 - Authenticated (Author+) Arbitrary File Deletion via Post Meta Field Injection","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.","image-optimization",null,"\u003C=1.7.4","1.7.5","high",8.1,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:U\u002FC:N\u002FI:H\u002FA:H","External Control of File Name or Path","2026-07-01 17:26:17","2026-07-02 05:35:07",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fa1a00374-e9d6-46f9-a28c-cb7768505787?source=api-prod",1,[22,23,24,25,26,27,28,29],"assets\u002Fbuild\u002F174.js","assets\u002Fbuild\u002F20.js","assets\u002Fbuild\u002F208.js","assets\u002Fbuild\u002F245.js","assets\u002Fbuild\u002F263.js","assets\u002Fbuild\u002F37.js","assets\u002Fbuild\u002F44.js","assets\u002Fbuild\u002F45.js","researched",false,3,"# Exploitation Research Plan - CVE-2026-5821\n\n## 1. Vulnerability Summary\nThe **Image Optimization – Compress Images and Convert to WebP or AVIF** plugin (versions \u003C= 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. \n\nThe 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.\n\n## 2. Attack Vector Analysis\n- **Endpoint:** `wp-admin\u002Fpost.php` (for both meta update and attachment deletion).\n- **Vulnerable Hook:** `delete_attachment`.\n- **Vulnerable Sink:** `File_System::delete($path)`.\n- **Payload Parameter:** The `metavalue` for the `image_optimizer_metadata` key.\n- **Preconditions:** \n    - Attacker must have at least **Author** level access (to upload and manage their own attachments).\n    - The target file must be writable\u002Fdeletable by the web server user (e.g., `www-data`).\n- **Required Knowledge:** The absolute path of the target file on the server.\n\n## 3. Code Flow\n1. **Entry Point:** A user with `delete_posts` capability (Author+) deletes an attachment.\n2. **Hook Trigger:** WordPress fires the `delete_attachment` hook.\n3. **Plugin Execution:** The plugin's registered callback `Image_Backup::remove($post_id)` (inferred) is executed.\n4. **Data Retrieval:** The function calls `get_post_meta($post_id, 'image_optimizer_metadata', true)`.\n5. **Payload Processing:** The code accesses the `backups` key from the returned meta array\u002Fobject:\n   ```php\n   \u002F\u002F Inferred logic based on description\n   $meta = get_post_meta($post_id, 'image_optimizer_metadata', true);\n   if (isset($meta['backups']) && is_array($meta['backups'])) {\n       foreach ($meta['backups'] as $backup_path) {\n           File_System::delete($backup_path); \u002F\u002F SINK\n       }\n   }\n   ```\n6. **Sink Execution:** `File_System::delete()` executes `unlink()` or a similar filesystem operation on the unvalidated `$backup_path`.\n\n## 4. Nonce Acquisition Strategy\nSince the attacker is an **Author**, they have access to the WordPress Admin dashboard. Nonces are required for updating post meta and deleting the post.\n\n1. **Meta Update Nonce:** Found in the attachment edit page (`wp-admin\u002Fpost.php?post=[ID]&action=edit`). The nonce for adding\u002Fupdating custom fields is typically named `_wpnonce` in the main edit form or specifically `addmeta` for the custom fields AJAX.\n2. **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]`.\n\n**Strategy:**\n- Use `browser_navigate` to go to the attachment edit page.\n- Use `browser_eval` to extract the `_wpnonce` from the form.\n- Use `browser_eval` to extract the `_wpnonce` from the \"Delete Permanently\" link.\n\n## 5. Exploitation Strategy\nThe goal is to delete a sensitive file (e.g., `wp-config.php` or a test file).\n\n1. **Step 1: Setup**\n   - Create an Author user.\n   - Create a dummy file at `\u002Ftmp\u002Fpwned.txt` to safely demonstrate deletion.\n2. **Step 2: Login and Upload**\n   - Login as the Author.\n   - Upload a legitimate image to get an attachment ID (`$ATTACH_ID`).\n3. **Step 3: Inject Payload into Post Meta**\n   - Navigate to the edit page for `$ATTACH_ID`.\n   - Use the Custom Fields interface to add or update the `image_optimizer_metadata` key.\n   - **Payload (Serialized PHP):** `a:1:{s:7:\"backups\";a:1:{i:0;s:14:\"\u002Ftmp\u002Fpwned.txt\";}}`\n   - *Note:* WordPress `get_post_meta` with `$single=true` will automatically `maybe_unserialize` this string into the array the plugin expects.\n4. **Step 4: Trigger Deletion**\n   - Submit a request to `post.php?action=delete&post=$ATTACH_ID&_wpnonce=$DEL_NONCE`.\n5. **Step 5: Verify**\n   - Check if `\u002Ftmp\u002Fpwned.txt` still exists.\n\n## 6. Test Data Setup\n- **Target File:** `\u002Ftmp\u002Fpwned.txt` (ensure web server has permission to delete).\n- **User:** Username: `attacker`, Password: `password123`, Role: `author`.\n- **Media:** A standard image file (e.g., `test.png`) uploaded by `attacker`.\n\n## 7. Expected Results\n- The request to `action=delete` returns a 302 redirect to the Media Library.\n- The attachment is removed from the database (`wp_posts` table).\n- The file `\u002Ftmp\u002Fpwned.txt` is successfully deleted from the filesystem.\n\n## 8. Verification Steps\n1. **Via WP-CLI:**\n   ```bash\n   # Check if attachment is gone\n   wp post exists [ID]\n   # Check if file is gone\n   ls \u002Ftmp\u002Fpwned.txt\n   ```\n2. **Check Database:**\n   ```bash\n   wp db query \"SELECT * FROM wp_postmeta WHERE post_id = [ID] AND meta_key = 'image_optimizer_metadata'\"\n   ```\n\n## 9. Alternative Approaches\nIf the Custom Fields UI is disabled or hidden:\n- **REST API:** Check if the Author can update meta via `POST \u002Fwp-json\u002Fwp\u002Fv2\u002Fmedia\u002F[ID]`. This requires the `image_optimizer_metadata` to be registered with `show_in_rest => true`.\n- **Direct AJAX:** Attempt to use the `add-meta` action in `admin-ajax.php` which is the backend for the Custom Fields UI:\n  ```http\n  POST \u002Fwp-admin\u002Fadmin-ajax.php\n  Content-Type: application\u002Fx-www-form-urlencoded\n  \n  action=add-meta&_ajax_nonce-add-meta=[NONCE]&post_id=[ID]&metakeyinput=image_optimizer_metadata&metavalue=[SERIALIZED_PAYLOAD]\n  ```","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.","\u002F\u002F Inferred from vulnerability description\n\u002F\u002F Path: includes\u002Fimage-backup.php\n\npublic function remove( $post_id ) {\n    $meta = get_post_meta( $post_id, 'image_optimizer_metadata', true );\n\n    if ( ! empty( $meta['backups'] ) && is_array( $meta['backups'] ) ) {\n        foreach ( $meta['backups'] as $file_path ) {\n            \u002F\u002F Vulnerable: $file_path is taken directly from post meta without path validation\n            File_System::delete( $file_path );\n        }\n    }\n}","--- includes\u002Fimage-backup.php\n+++ includes\u002Fimage-backup.php\n@@ -4,7 +4,11 @@\n     $meta = get_post_meta( $post_id, 'image_optimizer_metadata', true );\n     \n     if ( ! empty( $meta['backups'] ) && is_array( $meta['backups'] ) ) {\n+        $upload_dir = wp_upload_dir();\n         foreach ( $meta['backups'] as $file_path ) {\n-            File_System::delete( $file_path );\n+            \u002F\u002F Validate that the file path is located within the WordPress uploads directory\n+            if ( strpos( wp_normalize_path( $file_path ), wp_normalize_path( $upload_dir['basedir'] ) ) === 0 ) {\n+                File_System::delete( $file_path );\n+            }\n         }\n     }","1. Authenticate as an Author or higher and upload an image to the media library to generate a target attachment ID.\n2. Access the attachment's edit page in the WordPress admin dashboard to view the Custom Fields interface.\n3. 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., '\u002Fvar\u002Fwww\u002Fhtml\u002Fwp-config.php').\n4. Send a request to 'wp-admin\u002Fpost.php?action=delete' for the attachment ID, including the necessary security nonces obtained from the admin UI.\n5. 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.","gemini-3-flash-preview","2026-07-25 11:24:04","2026-07-25 11:24:58",{"type":42,"vulnerable_version":43,"fixed_version":11,"vulnerable_browse":44,"vulnerable_zip":45,"fixed_browse":46,"fixed_zip":47,"all_tags":48},"plugin","1.7.4","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fimage-optimization\u002Ftags\u002F1.7.4","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fimage-optimization.1.7.4.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fimage-optimization\u002Ftags\u002F1.7.5","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fimage-optimization.1.7.5.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fimage-optimization\u002Ftags"]