CVE-2026-40743

Tutor LMS – eLearning and online course solution <= 3.9.7 - Missing Authorization

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
3.9.8
Patched in
11d
Time to patch

Description

The Tutor LMS – eLearning and online course solution plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 3.9.7. This makes it possible for unauthenticated attackers to perform an unauthorized action.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
None
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=3.9.7
PublishedApril 20, 2026
Last updatedApril 30, 2026
Affected plugintutor

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan targets **CVE-2026-40743**, a Missing Authorization vulnerability in Tutor LMS (<= 3.9.7). The vulnerability allows unauthenticated attackers to perform unauthorized actions, typically via AJAX endpoints that fail to implement `current_user_can()` checks. --- ### 1. Vulnerabilit…

Show full research plan

This research plan targets CVE-2026-40743, a Missing Authorization vulnerability in Tutor LMS (<= 3.9.7). The vulnerability allows unauthenticated attackers to perform unauthorized actions, typically via AJAX endpoints that fail to implement current_user_can() checks.


1. Vulnerability Summary

  • Vulnerability: Missing Authorization
  • Affected Component: AJAX handlers registered via wp_ajax_nopriv_ (unauthenticated) or wp_ajax_ (authenticated) that lack internal capability checks.
  • Root Cause: The plugin registers a sensitive action (likely related to course management, instructor settings, or system configuration) and fails to verify if the requesting user has the necessary permissions (e.g., manage_options or tutor_instructor) before performing a state-changing operation.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action Name: To be determined via discovery (likely tutor_ajax_... or a registration-related action).
  • Authentication: None (Unauthenticated).
  • Parameter: action, _tutor_nonce (or similar), and action-specific data parameters.
  • Preconditions: The plugin must be active. If the vulnerability involves course enrollment, at least one course must exist.

3. Code Flow (Inferred/Discovery Path)

  1. Entry Point: An AJAX request is sent to admin-ajax.php with action=[VULNERABLE_ACTION].
  2. Hook Registration: The plugin defines the hook in a class like TUTOR\Ajax or within classes/Ajax.php using:
    add_action( 'wp_ajax_nopriv_[VULNERABLE_ACTION]', array( $this, '[CALLBACK_FUNCTION]' ) );
  3. Nonce Validation: The callback likely calls check_ajax_referer() or wp_verify_nonce(). If a nonce is required, it must be retrieved from the frontend (see Section 4).
  4. Vulnerable Sink: The [CALLBACK_FUNCTION] proceeds to update the database (e.g., update_option, wp_update_user, or $wpdb->update) without calling current_user_can().

4. Nonce Acquisition Strategy

Tutor LMS frequently localizes configuration data and nonces into a global JavaScript object named tutor_get_conf.

  1. Identify Trigger: Nonces are typically loaded on pages where Tutor LMS functionality is present (e.g., the Course Archive or a single Course page).
  2. Setup: Create a dummy course to ensure the scripts are enqueued.
    • wp post create --post_type=courses --post_title="Exploit Test" --post_status=publish
  3. Extraction:
    • Navigate to the homepage or the newly created course page.
    • Use browser_eval to extract the nonce:
      browser_eval("window.tutor_get_conf?.nonce")
    • If that fails, check for other common Tutor LMS keys: window.tutor_get_conf?.tutor_nonce or window.TutorLMSConfig?.nonce.

5. Exploitation Strategy

The specific vulnerable action needs to be identified. Based on common "Missing Authorization" flaws in Tutor LMS, we will test for unauthorized instructor registration or settings modification.

Phase A: Discovery

Search the plugin code for unauthenticated AJAX actions that perform updates:

grep -rn "wp_ajax_nopriv_" wp-content/plugins/tutor/ | grep -v "get_\|load_"

Note: Focus on actions that call functions involving update, delete, reset, or insert.

Phase B: Execution (Example: Unauthorized Setting Update)

Assuming the vulnerable action is tutor_place_order (unauthorized enrollment) or a settings reset.

Request Template:

  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Method: POST
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body:
    action=[IDENTIFIED_ACTION]&
    _tutor_nonce=[EXTRACTED_NONCE]&
    [PAYLOAD_PARAM]=[VALUE]
    

6. Test Data Setup

  1. Install Tutor LMS: Ensure version 3.9.7 is installed.
  2. Create Course:
    wp post create --post_type=courses --post_title="Target Course" --post_status=publish
    
  3. Identify Course ID: Use wp post list --post_type=courses to get the ID.
  4. Check Registration Settings: Ensure "Anyone can register" is enabled in WP settings if testing user-related actions.

7. Expected Results

  • Success: The server returns a successful response (often JSON {"success": true}) and the state change is reflected in the database.
  • Failure: The server returns 403 Forbidden, -1, or a JSON error indicating "Permission Denied".

8. Verification Steps

After sending the exploit request, verify the impact using WP-CLI:

  1. If Enrollment Exploit: Check if the unauthenticated "session" (or a target user) is now enrolled.
    wp db query "SELECT * FROM wp_posts WHERE post_type = 'tutor_enrolled'"
    
  2. If Settings Exploit: Check the target option value.
    wp option get [TARGET_OPTION_NAME]
    
  3. If User Promotion Exploit: Check the user capabilities.
    wp user list --role=tutor_instructor
    

9. Alternative Approaches

If the nopriv handlers are all properly authorized, investigate:

  1. Subscriber-level Authorization: Many Tutor LMS actions are registered for wp_ajax_ (authenticated) but only check for "logged in" status rather than specific capabilities.
    • Create a Subscriber user: wp user create attacker attacker@example.com --role=subscriber.
    • Obtain a nonce while logged in as Subscriber.
    • Attempt to access Instructor-level or Admin-level AJAX actions.
  2. REST API Endpoints: Check register_rest_route calls in Tutor LMS for missing permission_callback values.
    grep -rn "register_rest_route" wp-content/plugins/tutor/ -A 5
    
Research Findings
Static analysis — not yet PoC-verified

Summary

The Tutor LMS plugin for WordPress is vulnerable to unauthorized access in versions up to and including 3.9.7. This vulnerability arises because specific AJAX handlers lack internal capability checks, enabling unauthenticated attackers to execute unauthorized actions such as modifying course settings or instructor-level configurations.

Exploit Outline

1. Identify the targeted AJAX action registered via 'wp_ajax_nopriv_' or 'wp_ajax_' that lacks a 'current_user_can()' check within its callback function. 2. Navigate to the site's frontend (e.g., a course page) and extract a valid security nonce from the 'tutor_get_conf' or 'TutorLMSConfig' global JavaScript object. 3. Send a POST request to /wp-admin/admin-ajax.php with the 'action' parameter, the extracted nonce, and any required payload data for the unauthorized function. 4. Confirm execution by verifying changes to the plugin's configuration, user roles, or course data without the necessary administrative privileges.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.