TL;DR
Every LearnPress installation up to version 4.2.9.4 exposes a REST API handler that runs template callbacks intended only for administrators. Supplying a valid numeric course, lesson or quiz ID returns the rendered HTML, including hidden answer keys and internal curriculum. The request does not require authentication, so attackers can scrape premium content or undermine online examinations with a single curl command. Version 4.3.0 fixes the issue.
1. Summary
| CVE ID | CVE-2025-11368 |
| Affected Product(s) | LearnPress WordPress LMS plugin versions 1.x – 4.2.9.4 |
| Volerion Risk Score | 7.4 / 10 |
| Exploit Status | No public exploit archive but the attack can be reproduced with a single unauthenticated request |
| CISA KEV | Not listed |
Unauthenticated callers to /wp-json/lp/v1/load_content_via_ajax can invoke arbitrary template callbacks such as LP_Template_Course::course_curriculum_html or LP_Template_Quiz::questions_html, revealing material that should be visible only to enrolled students or site administrators.
2. Context – Why an LMS disclosure matters
LearnPress has over 200 000 active installations according to the WordPress.org statistics page. It is popular with small colleges, training providers and independent educators because it turns a standard WordPress site into a full-featured learning management system.
Course revenue often relies on gating content behind enrollment. In addition, quizzes are frequently used for graded examinations or continuing-education credits. Losing control of that data affects both commercial interests and academic integrity. Sites that host regulated training can even face compliance violations if answer keys leak.
3. Technical Details
The vulnerable route is registered in inc/rest-api/v1/frontend/class-lp-rest-ajax-controller.php:
register_rest_route( LP_REST_NAMESPACE, '/load_content_via_ajax', array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'load_content_via_ajax' ),
) );
Inside load_content_via_ajax the handler accepts two important parameters:
id– a numeric post ID pointing to a course, lesson, section, question or quizcallback– the fully qualified method name that should build the response HTML
There is no current_user_can() or nonce validation before the chosen callback is executed. If an attacker supplies an ID that belongs to restricted material and a callback like learn_press_get_template_part, the function renders the HTML exactly as the administrator would see it, including hidden data attributes that store correct answers for AJAX grading logic.
A minimal proof-of-concept looks like this:
curl -s \
-d 'id=123&callback=LP_Template_Quiz::questions_html' \
https://victim.example/wp-json/lp/v1/load_content_via_ajax \
| jq .
Replace 123 with a valid quiz post ID and the response includes a data-answer attribute for every question.
Version 4.3.0 introduces an early-exit check:
if ( ! current_user_can( 'edit_lp_course', $id ) ) {
return new WP_Error( 'lp_rest_forbidden', __( 'Sorry, you are not allowed to access this resource.' ), array( 'status' => 403 ) );
}
The patch also whitelists callbacks rather than accepting arbitrary method names, eliminating similar exposures in the future.
4. Impact
Attackers can harvest:
- Full course curricula, undermining paid content models
- Quiz questions with the correct answers, invalidating assessments
- Private lesson drafts or attachments meant only for instructors
Although no code execution is involved, the confidentiality breach can have severe business consequences. Subscription cancellations, plagiarism and exam fraud are realistic downstream effects. Because the endpoint is part of the standard REST namespace it commonly passes through caching proxies and web application firewalls uninspected, so many site owners will not notice exploitation.
5. Remediation
Upgrade LearnPress to version 4.3.0 or later. If an immediate upgrade is impossible, apply one of these temporary mitigations:
- Use a WordPress security plugin or server-level rule to block unauthenticated access to
/wp-json/lp/v1/load_content_via_ajax. - Add
add_filter( 'rest_authentication_errors', '__return_wp_error' );to a must-use plugin, which disables the entire REST API for visitors. Be aware this can break legitimate integrations.
After patching, rotate any quiz bank that may have been exposed and audit access logs for requests to the endpoint.
6. Timeline
| Date (UTC) | Milestone |
|---|---|
| 2025-11-21 06:15 | CVE-2025-11368 published |
| 2025-11-21 06:18 | Volerion completes enrichment and publishes risk score |
7. References
- Source code – route registration: https://plugins.trac.wordpress.org/browser/learnpress/trunk/inc/rest-api/v1/frontend/class-lp-rest-ajax-controller.php#L23
- Source code – vulnerable handler: https://plugins.trac.wordpress.org/browser/learnpress/trunk/inc/rest-api/v1/frontend/class-lp-rest-ajax-controller.php#L41
- Diff between 4.2.9.4 and 4.3.0: https://plugins.trac.wordpress.org/changeset?old_path=/learnpress/tags/4.2.9.4&new_path=/learnpress/tags/4.3.0&sfp_email=&sfph_mail=
- Wordfence advisory: https://www.wordfence.com/threat-intel/vulnerabilities/id/0c9856db-3779-4649-9a48-1c7b6d019816?source=cve
About Volerion
Volerion delivers AI-driven enrichment minutes after a CVE goes live. A single call to our REST API returns CVSS 4.0 vectors, exploitability metrics and affected products complete with remediation. Additionally, we offer different scoring profiles, complete with insight into the eight comprehensive categories that make up the final score. Our API is also available in the tradditional NVD API 2.0 format, so integration is as simple as swapping hosts. Spend less time parsing CVEs and more time closing them.
How the Volerion Risk Score fits with CVSS, EPSS and KEV
At the time of writing:
- This CVE is scored 7.5 using CVSS 3.1, reflecting high confidentiality impact with trivial network exploitation.
- EPSS assigns a score of 0.0000, indicating essentially no current prediction of exploitation based on public telemetry.
- The vulnerability is not present in CISA’s Known Exploited Vulnerabilities catalog.
The Volerion Risk Score blends these signals with additional context such as LearnPress market share and the effort required to update a WordPress plugin. The result is 7.4, placing the bug in our medium-high band that deserves prompt, but not emergency, attention.