CVE-2026-6965 Overview
CVE-2026-6965 is an Insecure Direct Object Reference (IDOR) vulnerability [CWE-639] in the Tutor LMS – eLearning and online course solution plugin for WordPress. The flaw affects all versions up to and including 3.9.9. The plugin's get_course_id_by() function trusts the user-supplied course GET parameter as the authoritative course ID for ownership lookups. This value is then consumed by can_user_manage(), the plugin's sole authorization gate for instructor-level operations. Authenticated attackers with instructor-level privileges can bypass authorization and perform unauthorized operations on other instructors' course content.
Critical Impact
Authenticated instructors can permanently delete lessons, quizzes, assignments, and Q&A threads, modify victim course content, manipulate student grades, and read unpublished content across any other instructor's course.
Affected Products
- Tutor LMS – eLearning and online course solution plugin for WordPress (versions ≤ 3.9.9)
- WordPress sites with instructor-level user roles configured via Tutor LMS
- Multi-instructor learning platforms using Tutor LMS for course delivery
Discovery Timeline
- 2026-05-13 - CVE-2026-6965 published to NVD
- 2026-05-13 - Last updated in NVD database
Technical Details for CVE-2026-6965
Vulnerability Analysis
The vulnerability is an Insecure Direct Object Reference flaw in the Tutor LMS plugin's authorization model. The plugin centralizes instructor permission checks in a single function, can_user_manage(), which verifies whether the current user is an instructor for a specified course. However, the course ID consumed by this gate is resolved through get_course_id_by(), which reads the course GET parameter directly from the request without cross-validating it against the parent course of the target content object.
An authenticated instructor can therefore supply a course parameter referencing one of their own courses while operating on lessons, quizzes, topics, announcements, or Q&A threads that actually belong to a different instructor's course. The authorization check succeeds because the attacker legitimately manages the course they named, not the course that owns the target object.
Root Cause
The root cause is a missing object-to-owner relationship check. The get_course_id_by() helper used in classes/Ajax.php, classes/Lesson.php, classes/Quiz.php, classes/Q_And_A.php, classes/Announcements.php, classes/Course.php, and classes/Utils.php unconditionally trusts the request-supplied course identifier. The plugin never reconciles the supplied course ID with the actual parent course derived from the target lesson, quiz, or topic ID, allowing the authorization gate to be evaluated against an attacker-controlled context.
Attack Vector
Exploitation requires authenticated access at instructor level or above. The attacker issues AJAX requests to vulnerable Tutor LMS endpoints — for example, lesson deletion, quiz modification, announcement creation, or Q&A thread removal — and supplies two object identifiers: the course parameter referencing a course they own, and a target object ID (lesson, quiz, topic, announcement, or thread) belonging to a victim course. The plugin authorizes the action against the attacker-owned course and executes the operation against the victim object. Cascading deletions on quizzes also remove associated student attempt records.
Refer to the source for the vulnerable function locations: WordPress Tutor Ajax Class, WordPress Tutor Lesson Class, WordPress Tutor Quiz Class, and WordPress Tutor Utils Class.
// No verified exploit code is published.
// Conceptually: authenticated instructor sends an AJAX request such as
// POST /wp-admin/admin-ajax.php
// action=<vulnerable_tutor_action>&course=<attacker_owned_course_id>&<target_object_id>=<victim_object_id>
// can_user_manage() evaluates membership against attacker_owned_course_id and authorizes the action.
Detection Methods for CVE-2026-6965
Indicators of Compromise
- Unexpected deletion of lessons, quizzes, assignments, topics, announcements, or Q&A threads in instructor-owned courses.
- WordPress audit log entries showing content modifications by instructor accounts not associated with the affected course.
- Student quiz attempt records disappearing simultaneously with quiz object deletions.
- Unexplained grade changes on student quiz submissions performed by accounts that do not own the parent course.
Detection Strategies
- Review web server access logs for admin-ajax.php requests where the course parameter and the target object's actual parent course ID do not match.
- Correlate WordPress user role data with Tutor LMS course ownership tables to flag write operations against content the requesting instructor does not own.
- Monitor database deletion events on Tutor LMS tables (tutor_quiz_attempts, posts of type lesson, tutor_quiz, tutor_assignments, tutor_announcements) initiated by non-owner accounts.
Monitoring Recommendations
- Enable a WordPress audit logging plugin to record content create, update, and delete actions with originating user IDs and IP addresses.
- Alert on bursts of Tutor LMS AJAX actions originating from a single instructor account targeting multiple distinct courses within a short time window.
- Periodically reconcile course-content ownership in the database to identify objects modified by users outside the instructor list.
How to Mitigate CVE-2026-6965
Immediate Actions Required
- Update the Tutor LMS plugin to a version newer than 3.9.9 that includes the fix referenced in the WordPress Tutor Changeset.
- Audit instructor accounts and remove or downgrade any that are inactive, untrusted, or unnecessary.
- Review recent course content changes, deletions, and grade adjustments to identify potential abuse before patching.
Patch Information
The vendor addressed the IDOR by hardening course ID resolution. Reference the Wordfence Vulnerability Intel advisory and the upstream commit in the WordPress Tutor Changeset. Apply the latest Tutor LMS release through the WordPress admin dashboard or via WP-CLI.
Workarounds
- Temporarily restrict the instructor role to trusted users only until the patched version is deployed.
- Deploy a Web Application Firewall (WAF) rule that inspects Tutor LMS AJAX actions and rejects requests where the course parameter does not match the parent course of the supplied target object ID.
- Take a full database backup before patching so that any unauthorized deletions discovered post-update can be recovered.
# Update Tutor LMS via WP-CLI to the latest patched release
wp plugin update tutor --path=/var/www/html
# Verify installed version is greater than 3.9.9
wp plugin get tutor --field=version --path=/var/www/html
# List users with instructor role to review access
wp user list --role=tutor_instructor --path=/var/www/html
: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


