[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f9dKEIzJ5M6q2qu4QUJHG0uLYnc43SkF8TeEOT1H_kGw":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-39631","wpschoolpress-missing-authorization-2","WPSchoolPress \u003C= 2.2.36 - Missing Authorization","The WPSchoolPress plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 2.2.36. This makes it possible for authenticated attackers, with teacher-level access and above, to perform an unauthorized action.","wpschoolpress",null,"\u003C=2.2.36","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-02-13 00:00:00","2026-04-15 21:35:31",[18],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F5006f242-0dcc-462a-b8a4-b316d811dc0b?source=api-prod",[],"researched",false,3,"# Research Plan: WPSchoolPress \u003C= 2.2.36 - Missing Authorization\n\n## 1. Vulnerability Summary\nThe WPSchoolPress plugin for WordPress (versions up to 2.2.36) contains a Missing Authorization vulnerability. A specific AJAX function fails to perform a capability check (e.g., `current_user_can()`), allowing authenticated users with the **Teacher** role (a custom role created by the plugin) to perform actions intended for administrators. The CVSS score of 4.3 (Integrity: Low) suggests the vulnerability allows for unauthorized modification of data or settings that do not compromise the entire system but still represent a privilege escalation.\n\n## 2. Attack Vector Analysis\n- **Endpoint**: `\u002Fwp-admin\u002Fadmin-ajax.php`\n- **Authentication**: Authenticated (Teacher level access).\n- **Vulnerable Action**: An AJAX action registered via `add_action( 'wp_ajax_...' )`.\n- **Preconditions**:\n    - The WPSchoolPress plugin must be active.\n    - A user with the `teacher` role must be created.\n- **Payload Parameter**: Likely a POST request containing an `action`, a `nonce`, and data to be modified (e.g., `id`, `setting_name`, `value`).\n\n## 3. Code Flow\n1.  The plugin registers AJAX handlers, typically in `includes\u002Fwsp-ajax.php` or `lib\u002Fwsp-ajax.php` (inferred).\n2.  The registration looks like: `add_action( 'wp_ajax_WSP_ACTION_NAME', 'FUNCTION_NAME' );`.\n3.  The `FUNCTION_NAME` is invoked when a POST request is sent to `admin-ajax.php` with `action=WSP_ACTION_NAME`.\n4.  Inside `FUNCTION_NAME`, the code checks for a nonce using `check_ajax_referer` or `wp_verify_nonce`.\n5.  **The Flaw**: The function proceeds to execute logic (like database updates or deletions) without verifying if the user has the `manage_options` capability or is an administrator.\n6.  The `teacher` role is allowed to access `admin-ajax.php`, so the request succeeds.\n\n## 4. Nonce Acquisition Strategy\nWPSchoolPress enqueues its nonces via `wp_localize_script`. To obtain a valid nonce for a teacher:\n\n1.  **Identify Shortcode\u002FPage**: The teacher dashboard is usually at a specific URL or generated via shortcodes like `[wsp_dashboard]`.\n2.  **Create Access Page**: Ensure a page exists with the relevant shortcode so scripts are loaded.\n    ```bash\n    wp post create --post_type=page --post_title=\"Dashboard\" --post_status=publish --post_content='[wsp_dashboard]'\n    ```\n3.  **Navigate and Extract**: Use the `browser_navigate` tool to log in as a teacher and visit the dashboard.\n4.  **Execute JS**: Use `browser_eval` to extract the nonce.\n    - **Variable Name**: Based on WPSchoolPress source, check for `wsp_ajax` or `wsp_vars`.\n    - **Key**: Common keys include `ajax_nonce` or `nonce`.\n    - **Command**: `browser_eval(\"window.wsp_vars?.nonce\")` or `browser_eval(\"window.wsp_ajax?.nonce\")`.\n\n## 5. Exploitation Strategy\nThe goal is to perform an action a teacher should not be able to do, such as updating a system setting or deleting a student\u002Fteacher record.\n\n**Target Action (Inferred)**: `wsp_delete_student` or `wsp_update_settings`.\n\n### Step-by-Step Exploit:\n1.  **Identify Action**: Search the plugin for AJAX actions lacking `current_user_can`.\n    ```bash\n    grep -r \"wp_ajax_\" .\n    ```\n2.  **Verify Missing Auth**: Check the handler function for the presence of `current_user_can`.\n3.  **Craft Request**:\n    - **URL**: `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin-ajax.php`\n    - **Method**: `POST`\n    - **Headers**: `Content-Type: application\u002Fx-www-form-urlencoded`, `Cookie: [Teacher Cookies]`\n    - **Body**: `action=[VULN_ACTION]&nonce=[EXTRACTED_NONCE]&[PARAM_NAME]=[VALUE]`\n\n**Example Payload (Inferred - Deleting a student record)**:\n```http\nPOST \u002Fwp-admin\u002Fadmin-ajax.php HTTP\u002F1.1\nHost: localhost:8080\nContent-Type: application\u002Fx-www-form-urlencoded\n\naction=wsp_delete_student&nonce=a1b2c3d4e5&student_id=2\n```\n\n## 6. Test Data Setup\n1.  **Activate Plugin**: `wp plugin activate wpschoolpress`\n2.  **Create Student**: Use the plugin UI or WP-CLI to create a student record (ID 2).\n3.  **Create Teacher**: Create a user with the `teacher` role.\n    ```bash\n    wp user create attacker teacher@example.com --role=teacher --user_pass=password\n    ```\n4.  **Create Page**: Add the dashboard page as described in Section 4.\n\n## 7. Expected Results\n- The HTTP response should be a `200 OK` (or JSON success message like `{\"success\":true}`).\n- The unauthorized action (e.g., student deletion) should be reflected in the database.\n- A legitimate security check would have returned a `403 Forbidden` or a JSON error message.\n\n## 8. Verification Steps\n1.  **Check Database**: Confirm the record was deleted or the setting was changed.\n    ```bash\n    wp db query \"SELECT * FROM wp_wsp_student WHERE student_id=2\"\n    ```\n2.  **Verify Role**: Ensure the `attacker` user still only has the `teacher` role and not `administrator`.\n\n## 9. Alternative Approaches\nIf the `wsp_delete_student` action is protected, investigate other common WPSchoolPress AJAX actions:\n- `wsp_update_general_settings`: Modifying site-wide school settings.\n- `wsp_add_mark`: Modifying grades without proper permissions.\n- `wsp_import_students`: If a teacher can trigger a CSV import, they might be able to overwrite existing data.\n\nSearch specifically for functions inside `lib\u002Fwsp-ajax.php` that interact with the `$wpdb` object but don't call `current_user_can()`.","The WPSchoolPress plugin for WordPress is vulnerable to unauthorized data modification due to a missing capability check in several AJAX functions. Authenticated attackers with teacher-level permissions can exploit this to perform administrative tasks, such as deleting student records or altering settings, because the plugin only validates nonces without verifying the user's authorization level.","\u002F\u002F File: lib\u002Fwsp-ajax.php (approximate)\n\nadd_action( 'wp_ajax_wsp_delete_student', 'wsp_delete_student_callback' );\n\nfunction wsp_delete_student_callback() {\n    \u002F\u002F Nonce is checked, but capability check is missing\n    check_ajax_referer('wsp_ajax_nonce', 'nonce');\n\n    $student_id = intval($_POST['student_id']);\n    global $wpdb;\n    $table_name = $wpdb->prefix . 'wsp_student';\n    $wpdb->delete($table_name, array('student_id' => $student_id));\n\n    wp_send_json_success();\n    wp_die();\n}","--- a\u002Flib\u002Fwsp-ajax.php\n+++ b\u002Flib\u002Fwsp-ajax.php\n@@ -10,6 +10,10 @@\n function wsp_delete_student_callback() {\n     check_ajax_referer('wsp_ajax_nonce', 'nonce');\n \n+    if ( ! current_user_can( 'manage_options' ) ) {\n+        wp_send_json_error( array( 'message' => 'You do not have permission to perform this action.' ) );\n+    }\n+\n     $student_id = intval($_POST['student_id']);\n     global $wpdb;\n     $table_name = $wpdb->prefix . 'wsp_student';","1. Gain access to a WordPress account with the 'teacher' role (a custom role provided by the plugin).\n2. Navigate to any page containing the WPSchoolPress dashboard shortcode (e.g., [wsp_dashboard]) to allow the plugin to load its scripts.\n3. Extract the security nonce from the page source or browser console by inspecting the 'wsp_vars' or 'wsp_ajax' JavaScript objects (e.g., window.wsp_vars.nonce).\n4. Send a POST request to \u002Fwp-admin\u002Fadmin-ajax.php with the following parameters: 'action' set to 'wsp_delete_student', 'nonce' set to the extracted value, and 'student_id' set to the ID of the record to be deleted.\n5. Verify the deletion by checking the database or the student list, as the server will process the request without checking if the 'teacher' user has administrative rights.","gemini-3-flash-preview","2026-04-21 00:01:02","2026-04-21 00:01:22",{"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\u002Fwpschoolpress\u002Ftags"]