Skip to main content
Vulnerability Database/CVE-2026-93388

CVE-2026-93388: Printcart Store WooCommerce Plugin RCE

CVE-2026-93388 is an unauthenticated arbitrary file upload vulnerability in Printcart Store plugin for WooCommerce that enables remote code execution. Attackers can exploit this flaw to upload malicious PHP files and execute arbitrary code on the server. This article covers technical details, affected versions, impact assessment, and mitigation strategies.

Published:

CVE-2026-93388 Overview

CVE-2026-93388 is an unauthenticated arbitrary file upload vulnerability in the Printcart Store (PCDesigner / NB Designer) plugin for WooCommerce. The flaw affects all versions up to and including 2.9.1 and leads to remote code execution on the hosting WordPress server. The vulnerable nbdesigner_copy_image_from_url AJAX action is registered through wp_ajax_nopriv_, exposing it to logged-out callers. Its Google Drive branch rebuilds the destination filename from the attacker-controlled gapi[name] parameter, bypassing the extension allow-list applied on the sibling branch. The classification maps to [CWE-434] Unrestricted Upload of File with Dangerous Type.

Critical Impact

Unauthenticated attackers can write a .php file into wp-content/uploads/nbdesigner/temp/ and execute arbitrary PHP code on the server.

Affected Products

  • Printcart Store (PCDesigner / NB Designer) plugin for WooCommerce
  • All versions through 2.9.1
  • WordPress sites with the printcart-integration plugin active

Discovery Timeline

  • 2026-10-14 - CVE-2026-93388 published to the National Vulnerability Database
  • 2026-10-14 - Last updated in NVD database

Technical Details for CVE-2026-93388

Vulnerability Analysis

The plugin registers the nbdesigner_copy_image_from_url AJAX handler under both authenticated and wp_ajax_nopriv_ hooks. Anonymous HTTP requests reach the handler without a WordPress session. The handler contains two branches: a standard URL branch that validates extensions against a jpg/jpeg/png/gif allow-list, and a Google Drive branch that constructs the saved filename from the raw gapi[name] request parameter. The Google Drive branch skips the allow-list check entirely.

The handler fetches bytes using the attacker-supplied Google Drive file identifier and OAuth token, then writes the response to wp-content/uploads/nbdesigner/temp/. Because that directory is web-accessible and PHP execution is not restricted there, a .php payload resolves and executes on request. The save-design nonce that gates the endpoint is handed out to anonymous callers by the nbd_check_use_logged_in endpoint, so the nonce check adds no effective barrier.

Root Cause

The root cause is missing file-type validation in the Google Drive upload branch combined with trust in client-supplied filename input. The sanitization and extension allow-list applied in the sibling branch were never ported to the Google Drive code path, leaving gapi[name] as an untrusted sink that controls the final filename and extension.

Attack Vector

An attacker retrieves a valid save-design nonce from the nbd_check_use_logged_in endpoint without authentication. The attacker then issues a POST request to admin-ajax.php invoking nbdesigner_copy_image_from_url with Google Drive parameters, supplying their own file identifier, OAuth token, and a gapi[name] value ending in .php. The server fetches the payload and writes it under wp-content/uploads/nbdesigner/temp/, where the attacker requests the file to trigger PHP execution. The vulnerability is network-reachable, requires no privileges, and needs no user interaction. See the Wordfence Vulnerability Report for additional analysis.

No verified exploit code is available. Refer to the WordPress Plugin Changeset for the vendor fix.

Detection Methods for CVE-2026-93388

Indicators of Compromise

  • Presence of unexpected .php, .phtml, or .phar files inside wp-content/uploads/nbdesigner/temp/ or related nbdesigner upload subdirectories.
  • POST requests to admin-ajax.php with action=nbdesigner_copy_image_from_url containing a gapi[name] parameter whose value ends in a scripting extension.
  • Anonymous GET requests to nbd_check_use_logged_in immediately followed by uploads from the same source address.

Detection Strategies

  • Scan WordPress upload directories for files whose extensions do not match the allowed image types for the Printcart plugin.
  • Alert on web server access logs showing direct requests to files beneath wp-content/uploads/nbdesigner/ with a .php suffix and a non-empty response.
  • Correlate wp_ajax_nopriv_ traffic patterns that include Google Drive OAuth tokens originating from external IP ranges.

Monitoring Recommendations

  • Forward WordPress access and PHP-FPM logs to a centralized store and build detections on the request patterns above.
  • Monitor file integrity in wp-content/uploads/ and raise alerts when new executable extensions appear.
  • Track outbound HTTPS connections from the PHP worker to googleapis.com endpoints that are not expected from the host.

How to Mitigate CVE-2026-93388

Immediate Actions Required

  • Update the Printcart Store (PCDesigner / NB Designer) plugin to version 2.9.2 or later immediately.
  • If an update cannot be deployed, deactivate and remove the printcart-integration plugin until patching is possible.
  • Inspect wp-content/uploads/nbdesigner/temp/ for unauthorized files and remove any non-image artifacts.
  • Rotate WordPress administrator credentials and application secrets if evidence of upload or execution exists.

Patch Information

The vendor remediated the issue in version 2.9.2 of the plugin. The code change is visible in the WordPress Plugin Version Comparison and the full fix diff in the WordPress Plugin Changeset.

Workarounds

  • Block web execution of PHP within wp-content/uploads/ using a web server rule set.
  • Restrict admin-ajax.php calls to the nbdesigner_copy_image_from_url action at the web application firewall when the request originates from unauthenticated sessions.
  • Deny access to the nbd_check_use_logged_in endpoint for anonymous callers until the plugin is updated.
bash
# Apache: disable PHP execution inside the WordPress uploads directory
# Place this in wp-content/uploads/.htaccess
<FilesMatch "\.(php|phtml|phar|phps)$">
    Require all denied
</FilesMatch>

# Nginx equivalent, inside the server block
location ~* /wp-content/uploads/.*\.(php|phtml|phar|phps)$ {
    deny all;
    return 403;
}

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.