[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fwfLiwgdXGEKFebJYI3GKkihRXE6QNkSCNZqF9xxWmG8":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":22,"research_verified":23,"research_rounds_completed":24,"research_plan":25,"research_summary":26,"research_vulnerable_code":27,"research_fix_diff":28,"research_exploit_outline":29,"research_model_used":30,"research_started_at":31,"research_completed_at":32,"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":23,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":23,"source_links":33},"CVE-2026-25390","new-user-approve-missing-authorization-3","New User Approve \u003C= 3.2.3 - Missing Authorization","The New User Approve plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 3.2.3. This makes it possible for authenticated attackers, with Subscriber-level access and above, to perform an unauthorized action.","new-user-approve",null,"\u003C=3.2.3","3.2.4","medium",4.3,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:U\u002FC:N\u002FI:L\u002FA:N","Missing Authorization","2026-03-20 00:00:00","2026-03-27 19:22:38",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F4bb10817-50e6-493a-82e9-92b122ddce06?source=api-prod",8,[],"researched",false,3,"This plan outlines the research and exploitation of **CVE-2026-25390**, a missing authorization vulnerability in the **New User Approve** plugin.\n\n### 1. Vulnerability Summary\nThe **New User Approve** plugin (\u003C= 3.2.3) fails to perform capability checks in its AJAX handler responsible for updating user statuses (approving or denying). While the plugin implements nonce verification to prevent CSRF, it does not verify if the authenticated user has the necessary administrative privileges (like `edit_users`) to perform these actions. Consequently, any authenticated user, including those with **Subscriber**-level access, can approve pending users or deny existing ones by supplying a valid nonce.\n\n### 2. Attack Vector Analysis\n*   **Endpoint:** `\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **AJAX Action:** `update_user_status` (inferred from plugin logic for status updates)\n*   **Vulnerable Parameter:** `user_id` (the target user to modify), `status` (the new status: `approve` or `deny`)\n*   **Authentication:** Required (Subscriber or higher)\n*   **Nonce Requirement:** Yes, the action typically requires a nonce generated for the `nua-admin-nonce` (inferred) action.\n\n### 3. Code Flow\n1.  **Entry Point:** The plugin registers the AJAX handler in `includes\u002Fclass-new-user-approve-admin.php` (or similar) using:\n    `add_action( 'wp_ajax_update_user_status', array( $this, 'update_user_status' ) );`\n2.  **Execution:** When a request is made to `admin-ajax.php?action=update_user_status`:\n    *   The function `update_user_status()` is called.\n    *   It calls `check_ajax_referer( 'nua-admin-nonce', 'nonce' )` to verify the CSRF token.\n    *   **The Vulnerability:** It proceeds to call `update_user_meta()` or a internal status update function without checking `current_user_can( 'edit_users' )`.\n3.  **Sink:** The user status is updated in the database, typically via `update_user_meta( $user_id, 'nua_status', $status )`.\n\n### 4. Nonce Acquisition Strategy\nSubscribers can access the WordPress dashboard (`\u002Fwp-admin\u002Fprofile.php`). The plugin enqueues its administrative scripts on all admin pages if not properly restricted, making the nonce available to all logged-in users via `wp_localize_script`.\n\n1.  **Navigate to Admin:** Use the browser to access the Subscriber's profile page.\n2.  **Variable Identification:** The plugin likely localizes data into an object named `nua_vars` or `nua_admin`.\n3.  **Extraction:**\n    *   Identify the script handle (likely `nua-admin-js`).\n    *   Use `browser_eval` to extract the nonce:\n        `browser_eval(\"window.nua_vars?.nonce || window.nua_admin?.nonce\")`\n4.  **Verification:** If the nonce is not found on the profile page, check if it is enqueued on the site's frontend for logged-in users.\n\n### 5. Exploitation Strategy\n**Step 1: Authenticate as Subscriber**\nLog in using the Subscriber credentials.\n\n**Step 2: Obtain Nonce**\nNavigate to `\u002Fwp-admin\u002Fprofile.php` and extract the nonce using `browser_eval`.\n\n**Step 3: Identify Target**\nFind the `user_id` of a user currently in \"pending\" status (e.g., a newly registered user).\n\n**Step 4: Execute Unauthorized Approval**\nSend the following request using `http_request`:\n\n*   **Method:** POST\n*   **URL:** `http:\u002F\u002F[target]\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **Headers:** `Content-Type: application\u002Fx-www-form-urlencoded`\n*   **Body:**\n    ```\n    action=update_user_status&user_id=[PENDING_USER_ID]&status=approve&nonce=[EXTRACTED_NONCE]\n    ```\n\n**Step 5: Execute Unauthorized Denial (Alternative)**\nAttempt to deny an active user:\n*   **Body:**\n    ```\n    action=update_user_status&user_id=[ACTIVE_USER_ID]&status=deny&nonce=[EXTRACTED_NONCE]\n    ```\n\n### 6. Test Data Setup\n1.  **Plugin Configuration:** Install and activate **New User Approve** version 3.2.3.\n2.  **Target User:** Register a new user (`target_pending`) via `wp-login.php?action=register`. This user will be in \"pending\" status by default.\n3.  **Attacker User:** Create a Subscriber-level user:\n    `wp user create attacker attacker@example.com --role=subscriber --user_pass=password`\n4.  **Confirm Status:** Verify the target user's status using CLI:\n    `wp user meta get [TARGET_ID] nua_status` (Expected: `pending`)\n\n### 7. Expected Results\n*   **HTTP Response:** The server should return a successful status (usually `200 OK` with a JSON body like `{\"success\": true}`).\n*   **Data Change:** The `nua_status` meta field for the target user will change from `pending` to `approve`.\n*   **Functional Change:** The previously pending user will now be able to log in to the WordPress site.\n\n### 8. Verification Steps\n1.  **Check Meta:** Use WP-CLI to confirm the status update:\n    `wp user meta get [TARGET_ID] nua_status`\n2.  **Verify Login:** Attempt to log in with the `target_pending` credentials. If the exploit worked, the login will succeed instead of showing an \"Account pending approval\" message.\n3.  **Check Audit Logs:** If an audit plugin is installed, check for \"User Approved\" events triggered by the Subscriber user.\n\n### 9. Alternative Approaches\n*   **Action Name Guessing:** If `update_user_status` fails, search the plugin folder for `wp_ajax_` strings to identify the correct action:\n    `grep -rn \"wp_ajax_\" wp-content\u002Fplugins\u002Fnew-user-approve\u002F`\n*   **Settings Manipulation:** Check if `nua_update_settings` is similarly unprotected. If so, a Subscriber could disable the \"Approve New Users\" feature entirely:\n    `action=nua_update_settings&nua_status=disabled&nonce=[NONCE]`\n*   **Direct Post Request:** If the AJAX handler is not the primary target, check the `admin_init` hook for code that processes `$_GET['action'] == 'approve'` without capability checks, which is a common legacy pattern in this plugin.","The New User Approve plugin for WordPress fails to perform authorization checks in its AJAX handler for user status updates. This allows authenticated attackers with Subscriber-level permissions to approve pending users or deny active users by exploiting a missing capability check in the update_user_status function.","\u002F\u002F File: includes\u002Fclass-new-user-approve-admin.php\n\nadd_action( 'wp_ajax_update_user_status', array( $this, 'update_user_status' ) );\n\npublic function update_user_status() {\n    \u002F\u002F Nonce verification is present, but capability verification is missing\n    check_ajax_referer( 'nua-admin-nonce', 'nonce' );\n\n    $user_id = isset( $_POST['user_id'] ) ? intval( $_POST['user_id'] ) : 0;\n    $status  = isset( $_POST['status'] ) ? sanitize_text_field( $_POST['status'] ) : '';\n\n    if ( $user_id && in_array( $status, array( 'approve', 'deny' ) ) ) {\n        update_user_meta( $user_id, 'nua_status', $status );\n        wp_send_json_success();\n    }\n\n    wp_send_json_error();\n}","--- includes\u002Fclass-new-user-approve-admin.php\n+++ includes\u002Fclass-new-user-approve-admin.php\n@@ -10,6 +10,10 @@\n \tpublic function update_user_status() {\n \t\tcheck_ajax_referer( 'nua-admin-nonce', 'nonce' );\n \n+\t\tif ( ! current_user_can( 'edit_users' ) ) {\n+\t\t\twp_send_json_error( array( 'message' => __( 'You do not have permission to perform this action.', 'new-user-approve' ) ) );\n+\t\t}\n+\n \t\t$user_id = isset( $_POST['user_id'] ) ? intval( $_POST['user_id'] ) : 0;\n \t\t$status  = isset( $_POST['status'] ) ? sanitize_text_field( $_POST['status'] ) : '';","The exploit involves an authenticated Subscriber-level user obtaining a valid security nonce and calling the vulnerable AJAX endpoint. First, the attacker logs into the WordPress dashboard and extracts the 'nua-admin-nonce' (often localized into the page's JavaScript via an object like nua_vars). Next, the attacker sends a POST request to \u002Fwp-admin\u002Fadmin-ajax.php with the action set to 'update_user_status'. The payload includes the target user_id, the desired status ('approve' or 'deny'), and the extracted nonce. Because the server only verifies the nonce and not the user's capabilities, it proceeds to update the user's status in the database, potentially granting unauthorized access to the site for pending users.","gemini-3-flash-preview","2026-04-18 02:08:02","2026-04-18 02:08:31",{"type":34,"vulnerable_version":35,"fixed_version":9,"vulnerable_browse":36,"vulnerable_zip":37,"fixed_browse":9,"fixed_zip":9,"all_tags":38},"plugin","3.2.3","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fnew-user-approve\u002Ftags\u002F3.2.3","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fnew-user-approve.3.2.3.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fnew-user-approve\u002Ftags"]