CVE-2026-1787

LearnPress Export Import <= 4.1.0 - Missing Authentication to Unauthenticated Migrated Course Deletion

mediumMissing Authorization
4.8
CVSS Score
4.8
CVSS Score
medium
Severity
4.1.1
Patched in
10d
Time to patch

Description

The LearnPress Export Import – WordPress extension for LearnPress plugin for WordPress is vulnerable to unauthorized loss of data due to a missing capability check on the 'delete_migrated_data' function in all versions up to, and including, 4.1.0. This makes it possible for unauthenticated attackers to delete course that have been migrated from Tutor LMS. The Tutor LMS plugin must be installed and activated in order to exploit the vulnerability.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:L
Attack Vector
Network
Attack Complexity
High
Privileges Required
None
User Interaction
None
Scope
Unchanged
None
Confidentiality
Low
Integrity
Low
Availability

Technical Details

Affected versions<=4.1.0
PublishedFebruary 11, 2026
Last updatedFebruary 21, 2026

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan is designed for an automated security agent to investigate and exploit **CVE-2026-1787** in the **LearnPress – Backup & Migration Tool** plugin. --- ### 1. Vulnerability Summary The **LearnPress Export Import** plugin (<= 4.1.0) contains a missing authorization vulnerability in …

Show full research plan

This research plan is designed for an automated security agent to investigate and exploit CVE-2026-1787 in the LearnPress – Backup & Migration Tool plugin.


1. Vulnerability Summary

The LearnPress Export Import plugin (<= 4.1.0) contains a missing authorization vulnerability in the function responsible for deleting data migrated from Tutor LMS. Specifically, the function delete_migrated_data (or similar) is hooked to an AJAX action that fails to perform a current_user_can() check or verify a nonce correctly, allowing unauthenticated attackers to trigger the deletion of courses migrated from Tutor LMS.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action (Inferred): lp_import_export_delete_migrated_data or lp_delete_migrated_data.
  • HTTP Method: POST
  • Required Parameter: action
  • Authentication: Unauthenticated (vulnerability is "Missing Authentication").
  • Preconditions:
    1. Tutor LMS plugin must be installed and active.
    2. Courses must have been migrated from Tutor LMS to LearnPress (or the system must perceive them as such via specific post meta).

3. Code Flow (Inferred)

  1. Entry Point: The plugin registers an AJAX handler, likely using add_action( 'wp_ajax_nopriv_...', ... ) or a general init hook that checks for a specific $_GET or $_POST trigger.
  2. Trigger: An HTTP POST request is sent to admin-ajax.php.
  3. Vulnerable Function: The execution reaches the handler function (e.g., delete_migrated_data).
  4. Missing Check: The function proceeds to identify migrated course IDs (likely by querying wp_posts for specific types or checking wp_postmeta for keys like _tutor_lms_migrated) and calls wp_delete_post() without validating that the requester has administrative privileges.
  5. Sink: Data is deleted from the database.

4. Nonce Acquisition Strategy

If the plugin requires a nonce for the AJAX action, it is likely exposed in the admin dashboard or on pages where the migration tool is active. Since the vulnerability is accessible to unauthenticated users, we must check if the nonce is leaked on the frontend.

  1. Identify Shortcodes: Search for shortcodes in the plugin: grep -r "add_shortcode" .
  2. Locate Nonce Variable: Search for wp_localize_script in the plugin directory to find the JS object name.
    • Search: grep -r "wp_localize_script" .
    • Likely Object: lp_import_export_settings or learnpress_export_import_data.
  3. Setup for Extraction:
    • Create a page with any identified shortcode or simply the LearnPress course archive:
      wp post create --post_type=page --post_status=publish --post_title="Migrate" --post_content="[lp_import_export_view]" (Guessing shortcode based on functionality).
  4. Extract via Browser:
    • browser_navigate("http://localhost:8080/migrate")
    • browser_eval("window.lp_import_export_settings?.nonce") (Replace with actual variable discovered in step 2).

5. Exploitation Strategy

The goal is to trigger the deletion of all courses migrated from Tutor LMS.

Step 1: Discover the AJAX Action
Search the plugin files for the string delete_migrated_data:
grep -rn "delete_migrated_data" /var/www/html/wp-content/plugins/learnpress-import-export/

Step 2: Identify the Hook
Look for the add_action call associated with that function. Note if it uses wp_ajax_nopriv_. If it only uses wp_ajax_ (authenticated), the exploit may rely on the fact that the check is missing in a more global hook like init or admin_init.

Step 3: Craft the Payload
Using the http_request tool, send the following POST request:

  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Header: Content-Type: application/x-www-form-urlencoded
  • Body: action=[ACTION_NAME]&nonce=[NONCE]
    (Note: If no nonce is found in the code, omit the nonce parameter).

6. Test Data Setup

To confirm the exploit, we must have "migrated" data in the database.

  1. Install Prerequisites:
    wp plugin install learnpress tutor --activate
  2. Create Tutor LMS Content (Simulated):
    # Create a LearnPress course
    COURSE_ID=$(wp post create --post_type=lp_course --post_title="Migrated Course" --post_status=publish --porcelain)
    # Add meta tagging it as migrated from Tutor LMS (Common pattern)
    wp post meta add $COURSE_ID _lp_import_source tutor-lms
    wp post meta add $COURSE_ID _tutor_course_id 123
    
  3. Verify Setup:
    wp post list --post_type=lp_course

7. Expected Results

  • Successful Exploit: The HTTP response should be 200 OK (often returning 1 or a JSON success message).
  • Database Impact: The course created in the setup phase should be deleted or moved to trash.

8. Verification Steps

After sending the HTTP request, verify the deletion using WP-CLI:

  1. Check Course Existence:
    wp post list --post_type=lp_course --post_status=any
    The "Migrated Course" should no longer appear in the list.
  2. Check Trash:
    wp post list --post_type=lp_course --post_status=trash
    Check if the course was permanently deleted or just trashed.

9. Alternative Approaches

If the wp_ajax_nopriv hook is not present:

  • Check admin_init: Search for the function being called within admin_init. In WordPress, admin-ajax.php triggers admin_init. If the function does not check current_user_can(), an unauthenticated request to admin-ajax.php?action=... will still execute the logic.
  • Parameter variations: The function might require specific parameters like source=tutor-lms to target specific data. Check the function definition for $_REQUEST or $_POST access.
  • Referer/Origin Checks: If the request fails, check if the plugin validates the Referer header and spoof it if necessary.
Research Findings
Static analysis — not yet PoC-verified

Summary

The LearnPress Export Import plugin for WordPress is vulnerable to unauthorized data loss due to a missing capability check in its 'delete_migrated_data' function. This allows unauthenticated attackers to delete courses migrated from Tutor LMS by triggering a vulnerable AJAX action, provided the Tutor LMS plugin is active.

Security Fix

--- a/inc/class-lp-import-export-ajax.php
+++ b/inc/class-lp-import-export-ajax.php
@@ -45,6 +45,10 @@
 	public function delete_migrated_data() {
+		if ( ! current_user_can( 'manage_options' ) ) {
+			return;
+		}
+
 		$source = isset( $_POST['source'] ) ? sanitize_text_field( $_POST['source'] ) : '';
 		if ( $source === 'tutor-lms' ) {
 			$this->delete_tutor_lms_migrated();
 		}

Exploit Outline

1. Identify the AJAX action associated with the migration tool's deletion logic (e.g., 'lp_import_export_delete_migrated_data' or 'lp_delete_migrated_data'). 2. Locate any required nonces by inspecting localized scripts or global JavaScript variables in the frontend (such as 'lp_import_export_settings'). 3. Send an unauthenticated HTTP POST request to '/wp-admin/admin-ajax.php' containing the 'action' and a 'source' parameter set to 'tutor-lms'. 4. The plugin will execute the 'delete_migrated_data' function, which queries for courses with the '_lp_import_source' meta key set to 'tutor-lms' and deletes them via 'wp_delete_post()' without verifying the attacker's permissions.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.