Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-15022

CVE-2026-15022: Tutor LMS WordPress SQLi Vulnerability

CVE-2026-15022 is a second-order SQL injection flaw in Tutor LMS for WordPress that allows authenticated attackers to extract sensitive database information. This article covers technical details, affected versions, and mitigation.

Published:

CVE-2026-15022 Overview

CVE-2026-15022 is a stored (second-order) SQL injection vulnerability in the Tutor LMS – eLearning and online course solution plugin for WordPress. The flaw affects all versions up to and including 4.0.0. The root cause is insufficient escaping of a user-supplied quiz answer array combined with an unprepared SQL query in the plugin's quiz data flow. Authenticated attackers with custom-level access or higher can persist a malicious payload through the wp_ajax_tutor_quiz_abandon handler. The injected SQL later executes when a privileged user or Tutor REST API key holder requests /wp-json/tutor/v1/quiz-attempt-details/{id}, enabling extraction of sensitive database contents. This vulnerability is tracked under [CWE-89].

Critical Impact

Authenticated low-privileged users can plant SQL payloads that execute in the context of privileged endpoint queries, exposing confidential WordPress database data including user credentials and course records.

Affected Products

  • Tutor LMS – eLearning and online course solution plugin for WordPress (all versions ≤ 4.0.0)
  • WordPress sites exposing the Tutor REST API endpoint /wp-json/tutor/v1/quiz-attempt-details/{id}
  • Sites permitting custom-level (student/instructor) account registration on vulnerable installs

Discovery Timeline

  • 2026-07-16 - CVE-2026-15022 published to NVD
  • 2026-07-16 - Last updated in NVD database

Technical Details for CVE-2026-15022

Vulnerability Analysis

The vulnerability is a second-order SQL injection. The injection sink and the injection source are separated across two request contexts. An authenticated attacker submits a crafted quiz answer array through the AJAX endpoint wp_ajax_tutor_quiz_abandon. The plugin stores that attacker-controlled input in the database without adequate escaping or parameterization. Later, when an administrator or a Tutor REST API key holder queries /wp-json/tutor/v1/quiz-attempt-details/{id}, the stored payload is concatenated into a live SQL query executed against the WordPress database. Because the query lacks wpdb->prepare() protection, attackers can append additional SQL statements to exfiltrate data such as user records, password hashes, and session tokens. The confidentiality impact is high while integrity and availability remain unchanged.

Root Cause

The defect combines two coding weaknesses. First, the quiz answer array supplied at attempt time is not validated or escaped before insertion. Second, the downstream query in helpers/QueryHelper.php (around line 951) and the REST API handlers in restapi/REST_Quiz.php build SQL using string concatenation instead of prepared statements. See the WordPress Tutor QueryHelper source and the Tutor REST Quiz handler.

Attack Vector

Exploitation requires an authenticated account with custom-level access such as a student or instructor role. The attacker sends a malicious payload to the wp_ajax_tutor_quiz_abandon handler, embedding SQL syntax within the quiz answer array. The payload lies dormant until a higher-privileged user or an integration using a Tutor REST API key loads the quiz attempt details, at which point the query executes with the database credentials of the WordPress install. Refer to the Wordfence vulnerability report for additional analysis.

No verified public exploit code is available. The vulnerability mechanism is documented in the plugin source at Quiz.php line 442 and Quiz.php line 626.

Detection Methods for CVE-2026-15022

Indicators of Compromise

  • Unexpected SQL syntax (UNION SELECT, SLEEP(, INFORMATION_SCHEMA) stored in the wp_tutor_quiz_attempts or related quiz attempt tables
  • POST requests to admin-ajax.php with action=tutor_quiz_abandon originating from low-privileged accounts and containing suspicious characters in the attempt_answers parameter
  • Requests to /wp-json/tutor/v1/quiz-attempt-details/{id} that return unusually large response payloads or trigger database errors in PHP logs

Detection Strategies

  • Inspect stored quiz attempt payloads for SQL metacharacters and keywords before they are consumed by the REST endpoint
  • Correlate wp_ajax_tutor_quiz_abandon submissions from a single low-privileged user with subsequent administrator or API access to quiz-attempt-details
  • Enable MySQL general query log or slow query log temporarily to identify malformed statements originating from Tutor LMS quiz functions

Monitoring Recommendations

  • Monitor WordPress wp-content/debug.log and PHP error logs for wpdb errors referencing tutor tables
  • Alert on new or unusual Tutor REST API key usage against the quiz-attempt-details endpoint
  • Baseline normal request rates for admin-ajax.php?action=tutor_quiz_abandon and alert on volume anomalies from individual accounts

How to Mitigate CVE-2026-15022

Immediate Actions Required

  • Update the Tutor LMS plugin to a version later than 4.0.0 that includes the vendor fix as soon as it becomes available
  • Audit existing custom-level user accounts and disable any that are unused or suspicious
  • Review stored quiz attempt records for SQL syntax in answer arrays and purge or sanitize affected rows

Patch Information

A fix must be applied by upgrading beyond the vulnerable 4.0.0 release. Consult the Wordfence vulnerability report and the Tutor LMS plugin repository for the fixed release. Rotate any Tutor REST API keys after patching.

Workarounds

  • Restrict access to /wp-json/tutor/v1/quiz-attempt-details/{id} at the web server or WAF layer to trusted IP ranges until the plugin is patched
  • Disable open user registration and require administrator approval for new Tutor LMS accounts
  • Deploy a WAF rule that inspects attempt_answers and related parameters posted to admin-ajax.php for SQL keywords such as UNION, SELECT, and --
bash
# Example NGINX rule to block low-privileged access to quiz-attempt-details until patched
location ~ ^/wp-json/tutor/v1/quiz-attempt-details/ {
    allow 10.0.0.0/8;      # trusted admin network
    deny all;
    include fastcgi_params;
    fastcgi_pass php-fpm;
}

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.