[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f6gxhtRZ96P7XpwXFJfBlchzXT8COL-vFIjm2oozL0nA":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":26,"research_verified":27,"research_rounds_completed":28,"research_plan":29,"research_summary":30,"research_vulnerable_code":9,"research_fix_diff":31,"research_exploit_outline":32,"research_model_used":33,"research_started_at":34,"research_completed_at":35,"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":27,"poc_model_used":9,"poc_verification_depth":9,"source_links":36},"CVE-2026-2712","wp-optimize-missing-authorization-to-authenticated-subscriber-plugin-settings-update-and-image-manipulation","WP-Optimize \u003C= 4.5.0 - Missing Authorization to Authenticated (Subscriber+) Plugin Settings Update and Image Manipulation","The WP-Optimize plugin for WordPress is vulnerable to unauthorized access of functionality due to missing capability checks in the `receive_heartbeat()` function in `includes\u002Fclass-wp-optimize-heartbeat.php` in all versions up to, and including, 4.5.0. This is due to the Heartbeat handler directly invoking `Updraft_Smush_Manager_Commands` methods without verifying user capabilities, nonce tokens, or the allowed commands whitelist that the normal AJAX handler (`updraft_smush_ajax`) enforces. This makes it possible for authenticated attackers, with Subscriber-level access and above, to invoke admin-only Smush operations including reading log files (`get_smush_logs`), deleting all backup images (`clean_all_backup_images`), triggering bulk image processing (`process_bulk_smush`), and modifying Smush options (`update_smush_options`).","wp-optimize",null,"\u003C=4.5.0","4.5.1","medium",5.4,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:U\u002FC:N\u002FI:L\u002FA:L","Incorrect Authorization","2026-04-09 11:52:37","2026-04-10 01:24:58",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F6a0a376e-ea3a-40ca-9341-f28f92e15e02?source=api-prod",1,[22,23,24,25],"changelog.txt","css\u002Fsmush-4-5-0.min.css","css\u002Fsortable\u002Fsortable-4-5-0.min.css","css\u002Fwp-optimize-admin-4-5-0.min.css","researched",false,3,"# Exploitation Research Plan: CVE-2026-2712\n\n## 1. Vulnerability Summary\nThe **WP-Optimize** plugin (up to version 4.5.0) contains an **Incorrect Authorization** vulnerability in its Heartbeat API integration. Specifically, the `receive_heartbeat()` function in `includes\u002Fclass-wp-optimize-heartbeat.php` fails to perform capability checks (`current_user_can`) or verify security nonces before executing commands intended for administrators.\n\nThe Heartbeat handler acts as a proxy, directly invoking methods in the `Updraft_Smush_Manager_Commands` class. While the standard AJAX handler (`updraft_smush_ajax`) properly restricts access, this Heartbeat-based entry point is accessible to any authenticated user, including those with **Subscriber-level** permissions. This allows an attacker to manipulate image optimization settings, delete backup images, and view logs.\n\n## 2. Attack Vector Analysis\n- **Endpoint**: `\u002Fwp-admin\u002Fadmin-ajax.php`\n- **Action**: `heartbeat`\n- **Method**: `POST`\n- **Authentication**: Required (Subscriber+)\n- **Vulnerable Hook**: `heartbeat_received` (Filter)\n- **Vulnerable File**: `includes\u002Fclass-wp-optimize-heartbeat.php`\n- **Vulnerable Function**: `receive_heartbeat()`\n- **Impact**: Unauthorized modification of plugin settings (`update_smush_options`), deletion of data (`clean_all_backup_images`), and information disclosure (`get_smush_logs`).\n\n## 3. Code Flow\n1. **Entry Point**: A user logged into WordPress (even as a Subscriber) triggers a Heartbeat request. This is a standard POST request to `admin-ajax.php` with `action=heartbeat`.\n2. **Hook Execution**: WordPress triggers the `heartbeat_received` filter.\n3. **Vulnerable Handler**: `WP_Optimize_Heartbeat::receive_heartbeat($response, $data)` is invoked.\n4. **Logic Path**:\n   - The function checks if `$data['wp-optimize']` is present.\n   - It iterates through the provided commands in the data.\n   - It directly calls methods in `Updraft_Smush_Manager_Commands` based on the input.\n   - **Critical Failure**: There is no check for `manage_options` capability or a specific WP-Optimize nonce inside this specific Heartbeat flow.\n5. **Sink**: The call reaches `Updraft_Smush_Manager_Commands::update_smush_options()`, which updates the `updraft_smush_options` row in the `wp_options` table.\n\n## 4. Nonce Acquisition Strategy\nThe WordPress Heartbeat API requires a standard WordPress Heartbeat nonce. This nonce is available to all logged-in users.\n\n1. **Access Site**: Use a Subscriber-level user to log in.\n2. **Retrieve Nonce**: Navigate to any admin page (e.g., `\u002Fwp-admin\u002Fprofile.php`). The Heartbeat nonce is localized by WordPress core.\n3. **Browser Eval**:\n   ```javascript\n   \u002F\u002F The Heartbeat nonce is typically stored in the heartbeatSettings object\n   window.heartbeatSettings?.nonce\n   ```\n4. **Verification**: Confirm the nonce is a 10-character hexadecimal string.\n\n## 5. Exploitation Strategy\n\n### Goal: Unauthorized Modification of Plugin Settings\nWe will attempt to disable image backups using the `update_smush_options` command.\n\n1. **Preparation**: Log in as a Subscriber.\n2. **Identify Target Command**: `update_smush_options`.\n3. **Construct Payload**:\n   The Heartbeat request expects a `data` parameter containing a JSON object or array.\n   - `action`: `heartbeat`\n   - `screen_id`: `profile` (or any valid admin screen)\n   - `_nonce`: [Heartbeat Nonce]\n   - `data[wp-optimize][smush][command]`: `update_smush_options`\n   - `data[wp-optimize][smush][data][options]`: A JSON object representing the new settings (e.g., setting `backup` to `false`).\n\n### Request Construction (using `http_request`)\n```http\nPOST \u002Fwp-admin\u002Fadmin-ajax.php HTTP\u002F1.1\nContent-Type: application\u002Fx-www-form-urlencoded\n\naction=heartbeat&screen_id=profile&_nonce=[NONCE]&data%5Bwp-optimize%5D%5Bsmush%5D%5Bcommand%5D=update_smush_options&data%5Bwp-optimize%5D%5Bsmush%5D%5Bdata%5D%5Boptions%5D%5Bbackup%5D=0\n```\n\n*Note: The exact structure of the `data` array may require slight adjustment based on how the plugin parses the nested array in `receive_heartbeat()`.*\n\n## 6. Test Data Setup\n1. **Install WP-Optimize**: Ensure version 4.5.0 is installed.\n2. **Configure Smush**: Ensure Smush is enabled in the admin settings.\n3. **Verify Current State**: Run `wp option get updraft_smush_options` and note that `backup` is likely `1` (true).\n4. **Create Attacker**: `wp user create attacker attacker@example.com --role=subscriber --user_pass=password123`.\n\n## 7. Expected Results\n- **Response**: The HTTP response will be a JSON object containing Heartbeat data. If successful, it might include a confirmation from the Smush command class within the `wp-optimize` key.\n- **Side Effect**: The `updraft_smush_options` entry in the database will be modified.\n\n## 8. Verification Steps\n1. **Check Options via CLI**:\n   ```bash\n   wp option get updraft_smush_options --format=json\n   ```\n   Verify that the `backup` field (or the target field used in the payload) has changed from its original value to `0`.\n2. **Check Logs (Optional)**:\n   Attempt to use the same method with the `get_smush_logs` command to see if logs are returned in the Heartbeat response:\n   ```http\n   data[wp-optimize][smush][command]=get_smush_logs\n   ```\n\n## 9. Alternative Approaches\nIf `update_smush_options` requires a more complex payload, try `clean_all_backup_images`. This command is often a simple string without additional data parameters.\n\n**Payload for Backup Deletion**:\n- `data[wp-optimize][smush][command]`: `clean_all_backup_images`\n\n**Verification for Backup Deletion**:\n1. Upload an image and smush it so a backup is created in `wp-content\u002Fuploads\u002Fwpo-plugins-tables-list.json` or the relevant backup directory.\n2. Run the exploit.\n3. Check if the backup files or the backup record is removed.","WP-Optimize versions up to 4.5.0 lack proper authorization and nonce checks within the Heartbeat API handler in `includes\u002Fclass-wp-optimize-heartbeat.php`. This allows authenticated users with Subscriber-level permissions or higher to execute administrative Smush commands, enabling them to modify plugin settings, delete image backups, and view logs.","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwp-optimize\u002F4.5.0\u002Fchangelog.txt \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwp-optimize\u002F4.5.1\u002Fchangelog.txt\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwp-optimize\u002F4.5.0\u002Fchangelog.txt\t2026-02-11 11:20:44.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwp-optimize\u002F4.5.1\u002Fchangelog.txt\t2026-03-25 10:42:14.000000000 +0000\n@@ -1,5 +1,25 @@\n == Changelog ==\n \n+= 4.5.1 - 23\u002FMar\u002F2026 =\n+\n+* FIX: Fixed compatibility issue with WP Remote \n+* FIX: Notice: Function _load_textdomain_just_in_time was called incorrectly \n+* FIX: Resolved weekly cron not running on WordPress \u003C 5.4 by switching to the wpo_weekly schedule\n+* FIX: Database table error when upgrading from free to premium version\n+* REFACTOR: Improved WebP conversion flow by separating capability checks from configuration changes\n+* REFACTOR: Improved auto-optimization handling by correcting static method usage\n+* REFACTOR: Introduced `WP_Optimize_Server_Compatibility` class to centralize all server environment checks\n+* REFACTOR: Removed separate `get_schedule_types()` method in premium version\n+* SECURITY: Enforced capability checks and allowed-command validation for Smush actions triggered via Heartbeat API. Thanks to WordFence for the responsible disclosure\n+* TWEAK: Display the `Enable the caching menu in the admin bar` option only when Cache or Minify is enabled\n+* TWEAK: Improved detection of LearnDash plugin tables\n+* TWEAK: Improved onboarding wizard RTL support and eliminated dependency on the PHP Reflection class\n+* TWEAK: Improved robustness of `uploads\u002Fwpo` directory removal during plugin uninstallation\n+* TWEAK: Minify - Don't remove the version query argument when the source is not processed by Minify\n+* TWEAK: Premium - Unused Images - Enhanced detection of edited WordPress images\n+* TWEAK: Prevent deprecation notices in PHP 8.5\n+* TWEAK: Add a notice when `.htaccess` file is not available or renamed in Apache servers\n+\n = 4.5.0 - 11\u002FFeb\u002F2026 =\n \n * FEATURE: Premium - Cache – Added ability to cache only selected URLs","An attacker with Subscriber-level access can exploit this by intercepting or generating a WordPress Heartbeat API request. By sending a POST request to `\u002Fwp-admin\u002Fadmin-ajax.php` with the `action` parameter set to `heartbeat` and a valid Heartbeat nonce, the attacker can include a `data[wp-optimize]` payload. This payload targets the Smush command processor (e.g., setting `data[wp-optimize][smush][command]` to `update_smush_options`) to modify plugin configurations or `clean_all_backup_images` to delete data. Because the `receive_heartbeat()` function fails to verify user capabilities (e.g., `manage_options`) before invoking the Smush command class, the request is processed with administrative privileges.","gemini-3-flash-preview","2026-04-16 16:23:10","2026-04-16 16:24:11",{"type":37,"vulnerable_version":38,"fixed_version":11,"vulnerable_browse":39,"vulnerable_zip":40,"fixed_browse":41,"fixed_zip":42,"all_tags":43},"plugin","4.5.0","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwp-optimize\u002Ftags\u002F4.5.0","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwp-optimize.4.5.0.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwp-optimize\u002Ftags\u002F4.5.1","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwp-optimize.4.5.1.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwp-optimize\u002Ftags"]