CVE-2026-93882 Overview
CVE-2026-93882 is an Insecure Direct Object Reference (IDOR) vulnerability in the LearnPress – WordPress LMS Plugin for Create and Sell Online Courses. The flaw affects all versions up to and including 4.4.8. Unauthenticated attackers can read and download course-material files from lessons in paid or enrollment-required courses. Exploitation requires that any single course on the site has 'No Required Enroll' enabled and owns at least one material file. The vulnerability is tracked under [CWE-639] (Authorization Bypass Through User-Controlled Key).
Critical Impact
Unauthenticated remote attackers can harvest premium course material files, including uploaded documents and external file URLs, bypassing enrollment and payment controls on affected WordPress LMS sites.
Affected Products
- LearnPress – WordPress LMS Plugin for Create and Sell Online Courses (versions ≤ 4.4.8)
- WordPress sites running LearnPress with at least one course set to 'No Required Enroll'
- Any LearnPress-powered site exposing the lp-ajax-handle endpoint (default configuration)
Discovery Timeline
- 2026-10-01 - CVE-2026-93882 published to NVD
- 2026-10-03 - Last updated in NVD database
Technical Details for CVE-2026-93882
Vulnerability Analysis
The vulnerability resides in the CourseMaterialTemplate::render_material_items() callback, which is reachable through the public lp-ajax-handle endpoint via the load_content_via_ajax action. The endpoint is explicitly registered in the AbstractAjax no-nonce allowlist. No nonce check or capability verification gates the request. The handler evaluates authorization using one attacker-supplied identifier (course_id) while retrieving material rows via a second, independently attacker-supplied identifier (item_id). This two-identifier pattern is the core defect because the lesson referenced by item_id is never validated as belonging to the authorized course.
Root Cause
The root cause is a broken object-level authorization check [CWE-639]. The code trusts the client to supply consistent identifiers. An attacker can pair the course_id of a free or 'No Required Enroll' course with the item_id of a lesson belonging to a different, paid course. The database query in class-lp-material-db.php returns the material rows for the requested item_id regardless of its parent course. The server then renders uploaded file paths and external URLs for those materials.
Attack Vector
An unauthenticated attacker sends a crafted POST or GET request to the WordPress lp-ajax-handle endpoint with the load_content_via_ajax action. The attacker supplies a course_id referring to any course on the site that satisfies the access precondition. The attacker then supplies an item_id referring to a lesson in a restricted or paid course. The server response contains the material metadata and file links for the restricted lesson. For technical specifics, see the Wordfence Vulnerability Analysis and the plugin source references for AbstractAjax.php and CourseMaterialTemplate.php.
Detection Methods for CVE-2026-93882
Indicators of Compromise
- Repeated unauthenticated POST or GET requests to /wp-admin/admin-ajax.php or /?lp-ajax=load_content_via_ajax from a single source.
- Request bodies containing both course_id and item_id parameters where the item_id does not belong to the referenced course_id.
- Spikes in outbound bandwidth from WordPress uploads directories tied to LearnPress course materials.
- Access-log patterns iterating sequential numeric item_id values against a stable course_id.
Detection Strategies
- Parse HTTP access logs for the lp-ajax-handle query parameter or load_content_via_ajax action from clients without authenticated WordPress session cookies.
- Correlate course_id and item_id values across requests to identify enumeration behavior.
- Deploy a web application firewall (WAF) rule that validates the lesson-to-course relationship before passing requests to WordPress.
Monitoring Recommendations
- Enable verbose logging in WordPress and front the site with a WAF capable of inspecting POST bodies.
- Alert on anomalous download volumes from /wp-content/uploads/learn-press/ and similar material storage paths.
- Track user-agent diversity and request rate against the LearnPress AJAX endpoint to spot scripted scraping.
How to Mitigate CVE-2026-93882
Immediate Actions Required
- Update the LearnPress plugin to a version later than 4.4.8 as soon as a fixed release is available from the vendor.
- Audit all courses and temporarily disable the 'No Required Enroll' option on every course until a patch is applied.
- Review access logs for prior exploitation attempts targeting the load_content_via_ajax action.
- Restrict access to /wp-admin/admin-ajax.php with WAF rules that enforce authentication for LearnPress AJAX actions.
Patch Information
No fixed version is listed in the enriched NVD data at the time of writing. Monitor the LearnPress plugin repository and the Wordfence advisory for the official security release that revises CourseMaterialTemplate::render_material_items() to validate that item_id belongs to course_id.
Workarounds
- Disable the 'No Required Enroll' option on every LearnPress course on the site to remove the exploitation precondition.
- Remove course material files from courses that must remain publicly accessible, hosting them elsewhere behind separate access controls.
- Deploy a WAF rule that blocks unauthenticated requests to the lp-ajax-handle endpoint carrying the load_content_via_ajax action.
- Temporarily deactivate the LearnPress plugin if course materials contain highly sensitive content and immediate patching is not possible.
# Example ModSecurity WAF rule to block unauthenticated LearnPress material loads
SecRule REQUEST_URI "@contains lp-ajax=load_content_via_ajax" \
"id:1009382,phase:2,deny,status:403,log,\
msg:'CVE-2026-93882 LearnPress IDOR attempt blocked',\
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.

