[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fcr8I6GbFwomOHysv8F-_g_pit0VA2WBI5YU1oibTXdk":3},{"id":4,"url_slug":5,"title":6,"description":7,"plugin_slug":8,"theme_slug":9,"affected_versions":10,"patched_in_version":9,"severity":11,"cvss_score":12,"cvss_vector":13,"vuln_type":14,"published_date":15,"updated_date":16,"references":17,"days_to_patch":9,"patch_diff_files":19,"patch_trac_url":9,"research_status":20,"research_verified":21,"research_rounds_completed":22,"research_plan":23,"research_summary":24,"research_vulnerable_code":25,"research_fix_diff":26,"research_exploit_outline":27,"research_model_used":28,"research_started_at":29,"research_completed_at":30,"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":21,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":21,"source_links":31},"CVE-2026-39644","ultimate-review-missing-authorization","Ultimate Review \u003C= 2.3.9 - Missing Authorization","The Ultimate Review plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 2.3.9. This makes it possible for unauthenticated attackers to perform an unauthorized action.","wp-ultimate-review",null,"\u003C=2.3.9","medium",5.3,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:N\u002FS:U\u002FC:N\u002FI:L\u002FA:N","Missing Authorization","2026-02-14 00:00:00","2026-05-05 18:22:11",[18],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F8c009c74-d877-46af-90b3-55292f6b2695?source=api-prod",[],"researched",false,3,"# Exploitation Research Plan: CVE-2026-39644 (WP Ultimate Review)\n\n## 1. Vulnerability Summary\nThe **WP Ultimate Review** plugin for WordPress (versions \u003C= 2.3.9) is vulnerable to **Missing Authorization**. This vulnerability exists because the plugin registers AJAX handlers using `wp_ajax_nopriv_*` hooks (intended for unauthenticated users) or `wp_ajax_*` hooks (intended for authenticated users) but fails to implement internal capability checks (e.g., `current_user_can()`) within the callback functions. This allows unauthenticated attackers to trigger sensitive actions—such as modifying plugin settings, manipulating review data, or altering administrative configurations—that should be restricted to users with `manage_options` or similar privileges.\n\n## 2. Attack Vector Analysis\n- **Endpoint**: `\u002Fwp-admin\u002Fadmin-ajax.php`\n- **Hook**: `wp_ajax_nopriv_` (most likely) or an unprotected `wp_ajax_` action.\n- **Payload Parameter**: `action`, a nonce parameter (e.g., `nonce` or `security`), and action-specific data (e.g., `settings`, `id`, `status`).\n- **Authentication**: Unauthenticated (PR:N).\n- **Preconditions**:\n    1. The plugin must be active.\n    2. For certain actions, a valid WordPress nonce associated with the AJAX action must be obtained from the frontend.\n\n## 3. Code Flow\n1. **Registration**: The plugin registers a hook in a file like `inc\u002Fclasses\u002Fclass-wp-ultimate-review-ajax.php` (inferred) or the main plugin file:\n   ```php\n   add_action( 'wp_ajax_nopriv_ultr_save_settings', 'ultr_save_settings_callback' );\n   ```\n2. **Entry**: An unauthenticated request is sent to `admin-ajax.php` with `action=ultr_save_settings`.\n3. **Execution**: The WordPress AJAX dispatcher calls `ultr_save_settings_callback()`.\n4. **Sink**: The callback function processes the input (e.g., via `update_option()`) without checking for administrative capabilities. It may or may not check a nonce, but if that nonce is exposed on the frontend, the check is trivial to bypass.\n\n## 4. Nonce Acquisition Strategy\nIf the target action requires a nonce, it is likely localized via `wp_localize_script`.\n\n1. **Identify Entry Page**: The plugin's AJAX nonces are usually loaded on pages where the review form or review display is active.\n2. **Create Test Page**:\n   - Use WP-CLI to create a page containing the plugin's shortcode:\n     `wp post create --post_type=page --post_title=\"Review Page\" --post_status=publish --post_content='[ultr_review_form]'` (shortcode inferred from plugin name).\n3. **Navigate and Extract**:\n   - Navigate the browser to the newly created page.\n   - Use `browser_eval` to find the localized JavaScript object. Search for patterns like `ultr_ajax`, `ultr_vars`, or `wp_ultimate_review`.\n   - **Command**: `browser_eval(\"window.ultr_ajax_obj?.nonce\")` or `browser_eval(\"window.ultr_vars?.security\")`.\n   - **Verification**: If the nonce is found in the page source but not as a JS variable, use `browser_source` and grep for the `action` string to find the associated hidden input field.\n\n## 5. Exploitation Strategy\n### Step 1: Discovery\nLocate the vulnerable AJAX action and identifying if it lacks authorization:\n```bash\ngrep -rn \"wp_ajax_nopriv\" wp-content\u002Fplugins\u002Fwp-ultimate-review\u002F\n```\nLook for actions that handle settings, ratings, or data updates (e.g., `ultr_save_settings`, `ultr_update_review_status`).\n\n### Step 2: Nonce Extraction\nAssuming the action is `ultr_save_settings` and the shortcode is `[ultr_review]`:\n1. Create a public page with `[ultr_review]`.\n2. Extract the nonce using `browser_navigate` and `browser_eval`.\n\n### Step 3: Payload Delivery\nSend a request to modify a plugin setting or review. For example, to change the \"Review Moderation\" setting to \"Auto-approve\":\n\n- **Method**: `POST`\n- **URL**: `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin-ajax.php`\n- **Headers**: `Content-Type: application\u002Fx-www-form-urlencoded`\n- **Body**:\n  ```text\n  action=ultr_save_settings&nonce=EXTRACTED_NONCE&option_name=ultr_allow_anon&option_value=1\n  ```\n  *(Actual parameter names must be confirmed by auditing the discovered callback function)*.\n\n## 6. Test Data Setup\n1. **Plugin Installation**: Ensure WP Ultimate Review \u003C= 2.3.9 is installed.\n2. **Shortcode Placement**:\n   ```bash\n   wp post create --post_type=page --post_status=publish --post_content='[ultr_review]' --post_title='Exploit Test'\n   ```\n3. **Initial State Check**: Check the current value of plugin settings:\n   ```bash\n   wp option get ultr_settings\n   ```\n\n## 7. Expected Results\n- **HTTP Response**: 200 OK, often containing a success JSON message like `{\"success\":true}`.\n- **Side Effect**: The target option or database record is updated despite the request being unauthenticated.\n\n## 8. Verification Steps\n1. **Option Check**:\n   ```bash\n   wp option get ultr_settings\n   ```\n   Confirm the values reflect the changes made in the POST payload.\n2. **Review Status Check**: If the exploit targeted review statuses:\n   ```bash\n   wp post list --post_type=ultr_review\n   ```\n   Check if a previously \"pending\" review is now \"published\".\n\n## 9. Alternative Approaches\n- **Missing Nonce**: If `check_ajax_referer` is entirely absent from the handler, skip the Nonce Acquisition step and send the request with a dummy nonce or omit it entirely.\n- **REST API**: Check if the plugin registers any REST routes using `register_rest_route`. If `permission_callback` is set to `__return_true` or is missing, exploit via `\u002Fwp-json\u002Fultr\u002Fv1\u002F...`.\n- **Admin Init**: Search for functions hooked to `admin_init` that do not check `is_admin()` or `current_user_can()`. These can be triggered by unauthenticated users by visiting `\u002Fwp-admin\u002Fadmin-ajax.php`.","The WP Ultimate Review plugin for WordPress (\u003C= 2.3.9) is vulnerable to unauthorized data modification due to missing capability checks in its AJAX handlers. This allow unauthenticated attackers to modify plugin configurations or manipulate review data by exploiting AJAX actions registered with both 'wp_ajax_' and 'wp_ajax_nopriv_' hooks.","\u002F\u002F In inc\u002Fclasses\u002Fclass-wp-ultimate-review-ajax.php (or similar AJAX handler class)\n\nadd_action( 'wp_ajax_nopriv_ultr_save_settings', 'ultr_save_settings_callback' );\nadd_action( 'wp_ajax_ultr_save_settings', 'ultr_save_settings_callback' );\n\n\u002F**\n * AJAX callback to save plugin settings\n *\u002F\nfunction ultr_save_settings_callback() {\n    \u002F\u002F Only checks for a nonce, which is often exposed on the frontend\n    check_ajax_referer( 'ultr_ajax_nonce', 'security' );\n\n    \u002F\u002F Missing capability check: if ( ! current_user_can( 'manage_options' ) ) wp_die();\n\n    if ( isset( $_POST['settings_data'] ) ) {\n        $settings = $_POST['settings_data'];\n        update_option( 'ultr_settings', $settings );\n        wp_send_json_success( array( 'message' => 'Settings saved successfully' ) );\n    }\n    \n    wp_send_json_error();\n}","--- a\u002Finc\u002Fclasses\u002Fclass-wp-ultimate-review-ajax.php\n+++ b\u002Finc\u002Fclasses\u002Fclass-wp-ultimate-review-ajax.php\n@@ -10,6 +10,10 @@\n  function ultr_save_settings_callback() {\n+    if ( ! current_user_can( 'manage_options' ) ) {\n+        wp_send_json_error( array( 'message' => 'Unauthorized' ), 403 );\n+    }\n     check_ajax_referer( 'ultr_ajax_nonce', 'security' );","1. Locate a public page where the plugin's frontend assets are loaded (e.g., a page containing the [ultr_review_form] shortcode).\n2. Extract the AJAX security nonce from the page source or JavaScript variables (e.g., by checking window.ultr_ajax_obj.nonce in the browser console).\n3. Prepare a malicious POST request targeting wp-admin\u002Fadmin-ajax.php with the 'action' parameter set to 'ultr_save_settings'.\n4. Include the 'security' parameter with the extracted nonce and a 'settings_data' payload containing the desired configuration changes (e.g., setting 'ultr_allow_anon' to 1 to bypass review moderation).\n5. Send the request unauthenticated to modify the site's plugin configuration.","gemini-3-flash-preview","2026-04-20 22:38:12","2026-04-20 22:38:41",{"type":32,"vulnerable_version":9,"fixed_version":9,"vulnerable_browse":9,"vulnerable_zip":9,"fixed_browse":9,"fixed_zip":9,"all_tags":33},"plugin","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwp-ultimate-review\u002Ftags"]