Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
🐘
🐘 Packagist
Not in CISA KEV
HIGH severity

CVE-2026-81891 — elFinder

HIGHFix: Studio-42/elFinder@191372c

CVE-2026-81891 is a high-severity (CVSS 8.1) Unrestricted File Upload vulnerability in Studio-42/elFinder. A fix is available for Studio-42/elFinder — see the affected versions and patch details below.

elFinder: ZIP extraction bypasses uploadDeny MIME filter allowing PHP file upload (RCE)

Also known asGHSA-gxmj-r5rf-ggwq
Published
Updated
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Oct 16, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

No confirmed exploitation observed yet

  • A successful exploit gives an attacker total control of the affected component, not partial access.
  • CISA’s own triage has not observed active exploitation or public proof-of-concept code for this CVE as of its last assessment.

Exploitation and automatability from CISA’s SSVC triage for CVE-2026-81891.

EPSS Exploitation Probability

via FIRST.org ↗
0.9%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs59th percentile — riskier than 59% of all scored CVEsHighest risk
0.03%0.49%0.95%1.40%0.5%0.9%0.9%Sep 26Oct 26Oct 26

Probability of exploitation in the next 30 days, from FIRST.org EPSS.

How urgent is this, really

CVE-2026-81891 by exploitation likelihood (EPSS) against impact (CVSS). Outside the shaded patch-first corner.

Where this sits among everything scored

Of 390,400 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Counts from FIRST.org, log-scaled.

Real-World Exposure

1 pkg affected
🐘Studio-42/elFinder

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects Packagist packages — download data is not available via public APIs for these ecosystems.

Description

Summary

elFinder provides uploadDeny and uploadAllow options in its connector configuration to restrict which MIME types may be uploaded. When uploadDeny includes text/x-php, direct upload of .php, .phtml, and .phar files is correctly blocked. However, the extract command (ZIP decompression) internally calls checkExtractItems(), which invokes mimetypeInternalDetect() directly without passing the result through mimeTypeNormalize(). Because phtml, phar, and similar PHP-executable extensions are absent from mime.types, they are not resolved to text/x-php at the detection stage, causing the MIME filter to be silently bypassed. An attacker who is permitted to upload ZIP archives can therefore extract PHP-executable files into the web-accessible files/ directory. If the server is configured to execute the affected extension (e.g., .phtml, .phar) as PHP — which is the case in common Apache and Nginx deployments — this results in Remote Code Execution.


Details

elFinder's MIME validation pipeline for direct uploads (upload command) is:

mimetype()
  └─ mimetypeInternalDetect()   // stage 1: extension → MIME via mime.types
  └─ mimeTypeNormalize()        // stage 2: apply staticMimeMap
       phtml:* → text/x-php
       phar:*  → text/x-php
       php5:*  → text/x-php
  └─ allowPutMime()             // blocked: text/x-php ∈ uploadDeny

The extract command (checkExtractItems() in elFinderVolumeDriver.class.php, line 7110) uses a shortened pipeline:

// line 7110 — stage 2 (mimeTypeNormalize) is never called
if ($chkMime
    && ($mimeByName = elFinderVolumeDriver::mimetypeInternalDetect($name))
    && !$this->allowPutMime($mimeByName)) {

Because phtml and phar are not present in mime.types, mimetypeInternalDetect() returns a generic type (e.g., application/octet-stream) for these extensions. Without mimeTypeNormalize(), the staticMimeMap entries that would map phtml:* → text/x-php are never applied, so allowPutMime() sees a non-blocked MIME and permits extraction.

Affected extensions confirmed: .phtml, .phar, .php5, .php3
Not bypassed: .php (present in mime.types, detected as text/x-php in stage 1)


PoC

Requirements:

  • elFinder 2.1.69 deployed under Apache/Nginx (PHP-FPM or mod_php)
  • Connector configured with uploadDeny = ['text/x-php'] and uploadAllow including application/zip
  • files/ directory served under a public web path

Step 1 — Confirm direct upload is blocked Open elFinder in a browser and click the Upload button.
Select hello.phtml (content: <?php phpinfo(); ?>).
→ Upload is rejected with: "Upload file hello.phtml: File type not allowed (text/x-php)" <img width="1061" height="408" alt="1" src="https://github.com/user-attachments/assets/22f833d9-7d2a-4197-85c2-3b0eb19ecfbc" />

Step 2 — Upload a ZIP containing the payload Create bypass.zip containing hello.phtml.
Upload bypass.zip via the Upload button.
→ ZIP is accepted (MIME: application/zip ∈ uploadAllow). <img width="886" height="320" alt="2" src="https://github.com/user-attachments/assets/30c3498f-91f4-45cf-8c2b-cc806716e3a4" />

Step 3 — Extract the ZIP Right-click bypass.zip in the file list → Extract files.
→ hello.phtml appears in the file list without any error.
→ File is now present at {files_dir}/hello.phtml on the server. <img width="1123" height="792" alt="3" src="https://github.com/user-attachments/assets/49e7db8e-566c-4653-a57f-e80fb31ea61d" />

Step 4 — Execute the extracted PHP file

Navigate to:

http://<target>/elFinder/files/hello.phtml

→ Apache processes the file as PHP and renders the full phpinfo() output, confirming Remote Code Execution.


<img width="1059" height="739" alt="4" src="https://github.com/user-attachments/assets/ad85fdf7-bdc7-4514-bdec-e45cfb2e2bd3" />

Impact

Any user with ZIP upload permission can bypass the uploadDeny MIME restriction, place PHP-executable files in a web-accessible directory, and achieve Remote Code Execution on the server.

Concrete impact:

  • Arbitrary PHP code execution on the web server
  • Full server environment disclosure via phpinfo() (paths, PHP version, loaded modules, environment variables)
  • Potential access to server filesystem, database credentials, and internal network services
  • Complete compromise of the web application if an attacker substitutes phpinfo() with a web shell (e.g., <?php system($_GET['cmd']); ?>)

Extensions confirmed executable on Apache (default config): phtml, phar, php5, php3

Recommended fix:

Apply mimeTypeNormalize() inside checkExtractItems() so that the full MIME pipeline is used consistently:

// elFinderVolumeDriver.class.php, line 7110
// Before (vulnerable):
$mimeByName = elFinderVolumeDriver::mimetypeInternalDetect($name)

// After (fixed):
$mimeByName = $this->mimeTypeNormalize(
    elFinderVolumeDriver::mimetypeInternalDetect($name),
    $name,
    pathinfo($name, PATHINFO_EXTENSION)
)


Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
🐘PackagistStudio-42/elFinderall versions2.1.70composer require Studio-42/elFinder:^2.1.70

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for Studio-42/elFinder, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update Studio-42/elFinder to 2.1.70 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2026-81891 is resolved across your whole dependency graph.

  3. Workarounds

    Treat uploaded files as untrusted until proven otherwise: validate the actual content type rather than the supplied extension, store uploads outside the web root on a volume mounted without execute permission, and rename them to server-generated identifiers so an attacker cannot choose the path a request will later resolve.

Frequently Asked Questions

### Summary elFinder provides `uploadDeny` and `uploadAllow` options in its connector configuration to restrict which MIME types may be uploaded. When `uploadDeny` includes `text/x-php`, direct upload of `.php`, `.phtml`, and `.phar` files is correctly blocked. However, the `extract` command (ZIP decompression) internally calls `checkExtractItems()`, which invokes `mimetypeInternalDetect()` directly without passing the result through `mimeTypeNormalize()`. Because `phtml`, `phar`, and similar PHP-executable extensions are absent from `mime.types`, they are not resolved to `text/x-php` at the
O3 Security · Impact-Aware SCA

Is CVE-2026-81891 in your dependencies?

Find it across Packagist, including transitive dependencies.

CVE-2026-81891: elFinder RCE — Fixed in 2.1.70