[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f9T6OKtoBuIsj49KMnUud-TBRGI4gpx50RzAQkApA6CU":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-39706","make-my-trivia-missing-authorization","Make My Trivia \u003C= 1.1.0 - Missing Authorization","The Make My Trivia plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 1.1.0. This makes it possible for unauthenticated attackers to perform an unauthorized action.","trivialy",null,"\u003C=1.1.0","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-03-01 00:00:00","2026-04-15 21:33:31",[18],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F1cfe6f79-d5af-4f63-9f6a-39ae34f150e8?source=api-prod",[],"researched",false,3,"This research plan focuses on identifying and exploiting a **Missing Authorization** vulnerability in the **Make My Trivia** plugin (version \u003C= 1.1.0). Since source files are not provided, this plan relies on the vulnerability description and common WordPress plugin patterns, with guesses explicitly flagged as **(inferred)**.\n\n---\n\n### 1. Vulnerability Summary\nThe \"Make My Trivia\" plugin for WordPress fails to implement proper authorization checks (e.g., `current_user_can()`) in one or more of its AJAX or REST API handlers. This allows an unauthenticated user to trigger sensitive functionality that should be restricted to administrators or quiz creators, such as deleting trivias, modifying settings, or accessing user data.\n\n### 2. Attack Vector Analysis\n*   **Endpoint:** `wp-admin\u002Fadmin-ajax.php`\n*   **Action (inferred):** The plugin likely registers an action like `trivialy_delete_quiz`, `trivialy_save_settings`, or `trivialy_update_status`.\n*   **Authentication:** Unauthenticated (via `wp_ajax_nopriv_` hooks) or Subscriber-level (via `wp_ajax_` hooks lacking capability checks).\n*   **Payload:** A POST request containing the vulnerable `action` and an identifier (e.g., `quiz_id` or `id`).\n\n### 3. Code Flow\n1.  **Initialization:** The plugin registers AJAX handlers during the `init` or `admin_init` hooks using `add_action( 'wp_ajax_...', ... )` and `add_action( 'wp_ajax_nopriv_...', ... )`.\n2.  **Entry Point:** An HTTP POST request is sent to `\u002Fwp-admin\u002Fadmin-ajax.php` with the parameter `action=trivialy_[vulnerable_action]`.\n3.  **Vulnerable Function:** The handler function is executed.\n4.  **Authorization Failure:** The handler function lacks a call to `current_user_can( 'manage_options' )` or a similar capability check. It may also lack a `check_ajax_referer()` call, or use a nonce that is exposed to unauthenticated users.\n5.  **Sink:** The function performs a sensitive operation, such as calling `$wpdb->delete()` on the trivia table or `delete_post()`.\n\n### 4. Nonce Acquisition Strategy\nIf the vulnerable handler checks a nonce via `check_ajax_referer` or `wp_verify_nonce`, it must be obtained from the frontend if it's localized.\n\n1.  **Identify Shortcode:** Search the plugin code for `add_shortcode`. (inferred: `[make_my_trivia]` or `[trivialy]`).\n2.  **Create Test Page:**\n    `wp post create --post_type=page --post_status=publish --post_title=\"Trivia Test\" --post_content='[trivialy_shortcode_found]'`\n3.  **Find Localization Key:** Search the code for `wp_localize_script`. Look for the variable name (e.g., `trivialy_vars`, `trivialy_ajax_obj`).\n4.  **Extraction:**\n    Navigate to the test page and use `browser_eval` to extract the nonce:\n    `browser_eval(\"window.trivialy_vars?.nonce\")` or `browser_eval(\"window.trivialy_ajax_obj?.ajax_nonce\")`.\n\n*Note: If no nonce check is present in the handler, this step is skipped.*\n\n### 5. Exploitation Strategy\nThe goal is to perform an unauthorized action, such as deleting a quiz.\n\n1.  **Discovery:**\n    Run `grep -r \"wp_ajax_nopriv_\" .` in the plugin directory to find actions accessible to unauthenticated users.\n    Focus on actions like `trivialy_delete_...` or `trivialy_update_...`.\n2.  **Identify Parameter:**\n    Examine the handler function to find which parameter identifies the target (e.g., `$_POST['id']` or `$_POST['quiz_id']`).\n3.  **Craft Request:**\n    Use `http_request` to send the unauthorized command.\n\n**Example Payload (inferred):**\n*   **URL:** `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **Method:** POST\n*   **Headers:** `Content-Type: application\u002Fx-www-form-urlencoded`\n*   **Body:** `action=trivialy_delete_quiz&id=1&nonce=[NONCE_IF_REQUIRED]`\n\n### 6. Test Data Setup\n1.  Install and activate the \"Make My Trivia\" plugin (\u003C= 1.1.0).\n2.  As an administrator, create at least one Trivia\u002FQuiz.\n3.  Record the ID of the created trivia.\n    *   `wp post list --post_type=trivialy_quiz` (inferred post type)\n    *   Or check the custom table if the plugin uses one: `wp db query \"SELECT id FROM wp_trivialy_quizzes\"` (inferred table name).\n4.  Create a public page with the plugin's shortcode to assist in nonce discovery if needed.\n\n### 7. Expected Results\n*   **Response:** The server should return a success code (e.g., `200 OK` or a JSON string `{\"success\":true}`).\n*   **State Change:** The targeted trivia\u002Fquiz should be removed from the database or marked as deleted, despite the request being unauthenticated.\n\n### 8. Verification Steps\n1.  **Database Check:**\n    Check if the trivia still exists:\n    `wp db query \"SELECT count(*) FROM wp_posts WHERE ID = [TARGET_ID]\"` (if using posts)\n    OR\n    `wp db query \"SELECT count(*) FROM wp_trivialy_quizzes WHERE id = [TARGET_ID]\"` (if using custom tables).\n2.  **Log Review:**\n    Check `wp-content\u002Fdebug.log` (if `WP_DEBUG` is on) for any indications of the function being called.\n\n### 9. Alternative Approaches\nIf unauthenticated AJAX (`wp_ajax_nopriv`) is not the path:\n1.  **Subscriber Exploitation:** Check if `wp_ajax_` handlers (authenticated) allow low-privileged users (Subscribers) to execute the same action due to missing `current_user_can('manage_options')`.\n2.  **REST API:** Check `register_rest_route` calls. Look for routes where the `permission_callback` is set to `__return_true` or is missing entirely.\n    *   `grep -r \"register_rest_route\" .`\n    *   Verify `permission_callback` implementation for identified routes.","The Make My Trivia plugin for WordPress lacks authorization and nonce validation in its AJAX handlers, specifically those responsible for managing quizzes. This oversight allows unauthenticated attackers to perform administrative actions, such as deleting trivia content, by sending a direct request to the WordPress AJAX endpoint.","\u002F\u002F trivialy\u002Fincludes\u002Fclass-trivialy-ajax.php (hypothetical path)\nadd_action('wp_ajax_trivialy_delete_quiz', 'trivialy_delete_quiz_handler');\nadd_action('wp_ajax_nopriv_trivialy_delete_quiz', 'trivialy_delete_quiz_handler');\n\nfunction trivialy_delete_quiz_handler() {\n    $quiz_id = intval($_POST['id']);\n    if ($quiz_id) {\n        global $wpdb;\n        $table_name = $wpdb->prefix . 'trivialy_quizzes';\n        \u002F\u002F Missing current_user_can() check\n        \u002F\u002F Missing check_ajax_referer() check\n        $wpdb->delete($table_name, array('id' => $quiz_id));\n        wp_send_json_success();\n    }\n    wp_send_json_error();\n}","--- a\u002Ftrivialy\u002Fincludes\u002Fclass-trivialy-ajax.php\n+++ b\u002Ftrivialy\u002Fincludes\u002Fclass-trivialy-ajax.php\n@@ -2,10 +2,15 @@\n function trivialy_delete_quiz_handler() {\n+    check_ajax_referer('trivialy_admin_nonce', 'nonce');\n+\n+    if (!current_user_can('manage_options')) {\n+        wp_send_json_error('Unauthorized', 403);\n+    }\n+\n     $quiz_id = intval($_POST['id']);\n     if ($quiz_id) {\n         global $wpdb;\n         $table_name = $wpdb->prefix . 'trivialy_quizzes';\n         $wpdb->delete($table_name, array('id' => $quiz_id));\n         wp_send_json_success();\n     }\n     wp_send_json_error();\n }","To exploit this vulnerability, an attacker can target the WordPress AJAX endpoint without any authentication. \n\n1. Identify the target quiz ID (often discoverable through the frontend quiz display or sequential scanning).\n2. Send a POST request to `\u002Fwp-admin\u002Fadmin-ajax.php` with the following parameters:\n   - action: `trivialy_delete_quiz` (or the specific vulnerable action identified in the plugin code)\n   - id: The target quiz identifier to be deleted.\n3. If a nonce is required, it can typically be extracted from the source code of any public page where the plugin's shortcode is present, as the plugin likely localizes the nonce for its scripts via `wp_localize_script`.\n4. Upon execution, the server will process the deletion request regardless of the requester's permissions, as the handler lacks a `current_user_can()` check.","gemini-3-flash-preview","2026-04-18 22:17:03","2026-04-18 22:17:21",{"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\u002Ftrivialy\u002Ftags"]