CVE-2026-16759 Overview
CVE-2026-16759 affects the Tutor LMS – eLearning and online course solution plugin for WordPress in all versions up to and including 4.0.5. The vulnerability allows unauthenticated attackers to invoke arbitrary zero-argument PHP functions server-side through the tutor_course_filter_ajax AJAX action. The flaw combines missing authorization with unsanitized array keys passed to PHP's extract() function inside tutor_load_template(). Attackers can abuse WordPress core edit_user() to create persistent subscriber-level accounts from request parameters, establishing footholds on affected sites. This is classified as [CWE-74] Improper Neutralization of Special Elements in Output Used by a Downstream Component (Injection).
Critical Impact
Unauthenticated remote attackers can invoke arbitrary zero-argument PHP functions and create persistent subscriber accounts on any WordPress site running Tutor LMS ≤ 4.0.5.
Affected Products
- Tutor LMS – eLearning and online course solution plugin for WordPress
- All versions up to and including 4.0.5
- Fixed in version 4.0.6
Discovery Timeline
- 2026-08-28 - CVE-2026-16759 published to NVD
- 2026-08-28 - Last updated in NVD database
Technical Details for CVE-2026-16759
Vulnerability Analysis
The vulnerability chains three separate weaknesses inside the Tutor LMS plugin. The tutor_course_filter_ajax AJAX action registers a handler without authorization or nonce checks, exposing it to unauthenticated requests. That handler forwards attacker-controlled data into tutor_load_template(), where user input flows into PHP's extract() function.
Because extract() converts array keys into local variable names, an attacker can overwrite the internal $template variable and control which template file is loaded. Once the vulnerable templates/single-content-loader.php template is selected, additional extract() behavior allows the attacker to overwrite $method_map and $context. The template then executes $method_map[$context](), invoking an attacker-chosen PHP function without arguments.
Zero-argument invocation still enables meaningful abuse. When combined with WordPress core edit_user(), which reads user data from $_POST, an attacker can persist a subscriber-level account entirely from request parameters. This provides authenticated access for follow-on attacks against additional plugin or theme surfaces.
Root Cause
The root cause is unsafe use of extract() on unsanitized input in tutor_load_template() (see lines 118 and 128 of includes/tutor-template-functions.php), combined with a missing authorization check on the tutor_course_filter_ajax handler in classes/Course_Filter.php. The single-content-loader.php template compounds the flaw by dispatching a callable through $method_map[$context]() (lines 30 and 71).
Attack Vector
The attack vector is network-based and unauthenticated. An attacker sends a crafted POST request to the WordPress AJAX endpoint (/wp-admin/admin-ajax.php) with action=tutor_course_filter_ajax and additional POST keys chosen to overwrite $template, $method_map, and $context via extract(). The server-side code then invokes the attacker's chosen zero-argument PHP function. By supplying WordPress user fields in the same POST body, the attacker triggers edit_user() to create a subscriber account. Refer to the Wordfence Vulnerability Report ID 65f68a49 for full technical details.
// Code example not provided - see vendor references for source-level details:
// - classes/Course_Filter.php lines 58, 224
// - includes/tutor-template-functions.php lines 118, 128
// - templates/single-content-loader.php lines 30, 71
Detection Methods for CVE-2026-16759
Indicators of Compromise
- POST requests to /wp-admin/admin-ajax.php containing action=tutor_course_filter_ajax from unauthenticated sessions.
- Unexpected new subscriber-level WordPress accounts created without corresponding registration flows or administrator action.
- Requests to the AJAX endpoint containing unusual parameter names that mirror PHP variable names such as template, method_map, or context.
- Web server access logs showing repeated POSTs to the Tutor LMS AJAX action from a single IP.
Detection Strategies
- Alert on unauthenticated invocations of tutor_course_filter_ajax where the request body includes parameters not defined by the plugin's legitimate front-end filters.
- Correlate new WordPress user creation events with recent access to the Tutor LMS AJAX endpoint.
- Inspect PHP error and access logs for entries referencing tutor_load_template or single-content-loader.php immediately preceding user account changes.
Monitoring Recommendations
- Enable WordPress audit logging for user creation, role changes, and plugin configuration modifications.
- Forward web server and PHP logs into a centralized log platform and retain them long enough to reconstruct attacker activity.
- Monitor the plugin's version state across managed WordPress installations and flag any sites still running 4.0.5 or earlier.
How to Mitigate CVE-2026-16759
Immediate Actions Required
- Upgrade Tutor LMS to version 4.0.6 or later on every WordPress site where it is installed.
- Audit the WordPress user list and remove any unrecognized subscriber accounts created since the plugin was deployed.
- Rotate credentials and secrets on any site suspected of compromise, and review recent plugin, theme, and admin-level changes.
Patch Information
The vendor fixed the vulnerability in Tutor LMS 4.0.6. See WordPress Tutor Changeset 3653079 for the patch to single-content-loader.php and the 4.0.5 to 4.0.6 diff for the complete change set.
Workarounds
- If patching is not immediately possible, deactivate the Tutor LMS plugin until the upgrade to 4.0.6 can be applied.
- Block unauthenticated POST requests to /wp-admin/admin-ajax.php where action=tutor_course_filter_ajax at the web application firewall.
- Restrict WordPress user registration to administrator approval and disable open registration where feasible.
# WAF rule concept: block unauthenticated Tutor LMS course filter AJAX requests
# Example ModSecurity-style rule
SecRule REQUEST_URI "@endsWith /wp-admin/admin-ajax.php" \
"chain,phase:2,deny,status:403,id:1026167590,msg:'Block CVE-2026-16759 exploit attempt'"
SecRule ARGS:action "@streq tutor_course_filter_ajax" \
"chain"
SecRule &REQUEST_COOKIES:/wordpress_logged_in_/ "@eq 0"
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

