CVE-2026-81891 Overview
elFinder is an open-source file manager for web applications, written in JavaScript using jQuery UI. A flaw in the archive extraction routine allows authenticated attackers with ZIP upload permission to write PHP-executable files into web-accessible directories. The checkExtractItems() function in php/elFinderVolumeDriver.class.php calls mimetypeInternalDetect() without normalizing the result through mimeTypeNormalize(). Because extensions like .phtml, .phar, .php5, and .php3 are missing from mime.types, MIME-based upload restrictions fail to block them. Attackers can achieve remote code execution when the web server processes the extracted files. The issue is tracked as CWE-434: Unrestricted Upload of File with Dangerous Type and fixed in version 2.1.70.
Critical Impact
Authenticated attackers with archive upload rights can bypass uploadDeny filters and execute arbitrary PHP code on the underlying web server.
Affected Products
- elFinder versions prior to 2.1.70
- Web applications embedding elFinder with PHP-enabled files/ directories
- Deployments relying on uploadDeny for text/x-php MIME filtering
Discovery Timeline
- 2026-08-31 - CVE-2026-81891 published to NVD
- 2026-09-01 - Last updated in NVD database
Technical Details for CVE-2026-81891
Vulnerability Analysis
The vulnerability resides in elFinder's archive extraction workflow. When a user uploads a ZIP archive and triggers extraction, checkExtractItems() iterates over entries and invokes elFinderVolumeDriver::mimetypeInternalDetect() to determine each file's MIME type. The result is passed directly to allowPutMime() without first being normalized by mimeTypeNormalize().
Normalization is the step that consults staticMimeMap, which explicitly maps PHP-alias extensions such as .phtml, .phar, .php5, and .php3 to text/x-php. Without normalization, these extensions produce a MIME value derived only from mime.types, where they are absent. The MIME check therefore returns a benign type, and uploadDeny rules configured to block text/x-php are silently bypassed.
Because elFinder is commonly deployed with a files/ directory that is directly reachable over HTTP, the extracted PHP files can be requested by the attacker and executed by the PHP interpreter, yielding remote code execution in the web server's context.
Root Cause
The root cause is inconsistent MIME resolution between upload and extraction paths. The upload handler routes detection through mimeTypeNormalize(), which honors staticMimeMap. The extraction path does not, creating a semantic gap between the allow-list logic and the actual file type on disk.
Attack Vector
An attacker with ZIP upload permission crafts an archive containing files with .phtml, .phar, .php5, or .php3 extensions. After uploading the archive, the attacker invokes elFinder's extract action. The MIME check misclassifies the entries, allowPutMime() returns true, and the PHP files are written to the target directory. The attacker then issues an HTTP request to the extracted file to execute arbitrary code.
}
}
} else {
- if ($chkMime && ($mimeByName = elFinderVolumeDriver::mimetypeInternalDetect($name)) && !$this->allowPutMime($mimeByName)) {
- self::localRmdirRecursive($p);
- $res['mimes'][] = $p;
- $res['rmNames'][] = $utf8Name;
- continue;
+ if ($chkMime) {
+ $mimeByName = $this->mimeTypeNormalize(
+ elFinderVolumeDriver::mimetypeInternalDetect($name),
+ $name,
+ pathinfo($name, PATHINFO_EXTENSION)
+ );
+
+ if ($mimeByName && !$this->allowPutMime($mimeByName)) {
+ self::localRmdirRecursive($p);
+ $res['mimes'][] = $p;
+ $res['rmNames'][] = $utf8Name;
+ continue;
+ }
}
$res['totalSize'] += (int)sprintf('%u', filesize($p));
}
Source: GitHub Commit Fix dd73e70
Detection Methods for CVE-2026-81891
Indicators of Compromise
- Presence of .phtml, .phar, .php5, or .php3 files within elFinder-managed files/ directories that were not deployed by administrators
- ZIP archives uploaded via elFinder followed by extract API calls (cmd=extract) originating from the same session
- Web server access logs showing GET or POST requests to newly created PHP files under elFinder upload paths
- Outbound network connections from the PHP-FPM or Apache process to unfamiliar hosts shortly after archive extraction
Detection Strategies
- Monitor file creation events for PHP-alias extensions inside directories writable by the web server user
- Alert on elFinder extract commands where archive contents include files matching PHP execution patterns
- Correlate archive upload activity with subsequent HTTP requests to newly written files in the same path
Monitoring Recommendations
- Enable web server access logging and forward logs to a centralized analytics platform for retention and query
- Track process lineage for PHP interpreters spawning shell, curl, wget, or reverse-shell binaries
- Baseline the contents of elFinder upload directories and alert on deviations
How to Mitigate CVE-2026-81891
Immediate Actions Required
- Upgrade elFinder to version 2.1.70 or later, which routes checkExtractItems() MIME detection through mimeTypeNormalize()
- Audit files/ and other elFinder-managed directories for unauthorized .phtml, .phar, .php5, or .php3 files
- Restrict archive upload and extraction permissions to trusted, authenticated users only
- Rotate credentials and inspect web shells if suspicious PHP files are found
Patch Information
The fix is available in elFinder Release 2.1.70. See the GitHub Security Advisory GHSA-gxmj-r5rf-ggwq and the corrective commit dd73e70 for technical details.
Workarounds
- Configure the web server to deny execution of PHP files within elFinder upload directories using <Directory> or location blocks
- Disable the archive extraction feature by removing zip from allowed archiveMimes in the elFinder volume configuration
- Add .phtml, .phar, .php5, and .php3 to explicit deny lists at both the MIME and extension layers
# Apache: block PHP execution in elFinder upload directory
<Directory "/var/www/html/files">
php_admin_flag engine off
<FilesMatch "\.(php|phtml|phar|php3|php5)$">
Require all denied
</FilesMatch>
</Directory>
# Nginx equivalent
location ^~ /files/ {
location ~ \.(php|phtml|phar|php3|php5)$ { deny all; }
}
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.