{"id":"CVE-2026-81891","aliases":["EUVD-2026-68800","GHSA-gxmj-r5rf-ggwq"],"status":"published","title":"elFinder: ZIP extraction bypasses uploadDeny MIME filter allowing PHP file upload (RCE)","description":"elFinder is an open-source file manager for web, written in JavaScript using jQuery UI. Prior to 2.1.70, checkExtractItems() in php/elFinderVolumeDriver.class.php calls mimetypeInternalDetect() without passing the result through mimeTypeNormalize(). Because the .phtml, .phar, .php5, and .php3 extensions are absent from mime.types, the staticMimeMap entries that map them to text/x-php are not applied, and allowPutMime() permits extraction even when uploadDeny blocks text/x-php. An attacker with ZIP upload permission can extract PHP-executable files into a web-accessible files/ directory and achieve remote code execution when the server executes those extensions. This issue is fixed in version 2.1.70.","severity":{"version":"3.1","score":8.1,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"high","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-11","score":0.00904,"percentile":0.6022,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-434"],"published":"2026-08-31T20:33:22Z","modified":"2026-10-28T02:30:45Z","fixes":[{"ecosystem":"Packagist","package":"Studio-42/elFinder","fixed_in":["2.1.70"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"Packagist","package":"Studio-42/elFinder","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.1.70"}]}]},{"source":"osv","ecosystem":"Packagist","package":"Studio-42/elFinder","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.1.70"}]}]}],"products":[{"vendor":"studio-42","product":"elfinder"}],"references":[{"url":"https://github.com/Studio-42/elFinder/security/advisories/GHSA-gxmj-r5rf-ggwq","tags":["x_refsource_CONFIRM","advisory","web"]},{"url":"https://github.com/Studio-42/elFinder/commit/191372c1bbebbd36fb55af79a84b9984861390ff","tags":["x_refsource_MISC","fix","web"]},{"url":"https://github.com/Studio-42/elFinder/commit/dd73e702820c146a192969800ee674ecdb208365","tags":["x_refsource_MISC","fix","web"]},{"url":"https://github.com/Studio-42/elFinder/releases/tag/2.1.70","tags":["x_refsource_MISC","web"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-81891","tags":["advisory"]},{"url":"https://github.com/advisories/GHSA-gxmj-r5rf-ggwq"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/81xxx/CVE-2026-81891.json","tags":["advisory"]},{"url":"https://github.com/Studio-42/elFinder","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2026-81891","title":"elFinder: ZIP extraction bypasses uploadDeny MIME filter allowing PHP file upload (RCE)","description":"elFinder is an open-source file manager for web, written in JavaScript using jQuery UI. Prior to 2.1.70, checkExtractItems() in php/elFinderVolumeDriver.class.php calls mimetypeInternalDetect() without passing the result through mimeTypeNormalize(). Because the .phtml, .phar, .php5, and .php3 extensions are absent from mime.types, the staticMimeMap entries that map them to text/x-php are not applied, and allowPutMime() permits extraction even when uploadDeny blocks text/x-php. An attacker with ZIP upload permission can extract PHP-executable files into a web-accessible files/ directory and achieve remote code execution when the server executes those extensions. This issue is fixed in version 2.1.70.","status":"published","published":"2026-08-31T20:33:22.283Z","modified":"2026-09-01T14:58:22.211Z","cvss":[{"version":"3.1","score":8.1,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"high","assessor":"cna"}],"cwes":["CWE-434"],"updated_at":"2026-11-02T13:36:29.327819Z"}],"euvd":[{"id":"EUVD-2026-68800","description":"elFinder is an open-source file manager for web, written in JavaScript using jQuery UI. Prior to 2.1.70, checkExtractItems() in php/elFinderVolumeDriver.class.php calls mimetypeInternalDetect() without passing the result through mimeTypeNormalize(). Because the .phtml, .phar, .php5, and .php3 extensions are absent from mime.types, the staticMimeMap entries that map them to text/x-php are not applied, and allowPutMime() permits extraction even when uploadDeny blocks text/x-php. An attacker with ZIP upload permission can extract PHP-executable files into a web-accessible files/ directory and achieve remote code execution when the server executes those extensions. This issue is fixed in version 2.1.70.","status":"published","published":"2026-08-31T20:33:22Z","modified":"2026-09-01T14:58:22Z","cvss":[{"version":"3.1","score":8.1,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"high"}],"updated_at":"2026-11-02T18:01:18.264709Z"}],"ghsa":[{"id":"GHSA-gxmj-r5rf-ggwq","title":"elFinder: ZIP extraction bypasses uploadDeny MIME filter allowing PHP file upload (RCE)","description":"### Summary\n\nelFinder 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.\n\n---\n\n### Details\n\nelFinder's MIME validation pipeline for **direct uploads** (`upload` command) is:\n\n```\nmimetype()\n  └─ mimetypeInternalDetect()   // stage 1: extension → MIME via mime.types\n  └─ mimeTypeNormalize()        // stage 2: apply staticMimeMap\n       phtml:* → text/x-php\n       phar:*  → text/x-php\n       php5:*  → text/x-php\n  └─ allowPutMime()             // blocked: text/x-php ∈ uploadDeny\n```\n\nThe `extract` command (`checkExtractItems()` in `elFinderVolumeDriver.class.php`, line 7110) uses a **shortened** pipeline:\n\n```php\n// line 7110 — stage 2 (mimeTypeNormalize) is never called\nif ($chkMime\n    \u0026\u0026 ($mimeByName = elFinderVolumeDriver::mimetypeInternalDetect($name))\n    \u0026\u0026 !$this-\u003eallowPutMime($mimeByName)) {\n```\n\nBecause `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.\n\n**Affected extensions confirmed:** `.phtml`, `.phar`, `.php5`, `.php3`  \n**Not bypassed:** `.php` (present in `mime.types`, detected as `text/x-php` in stage 1)\n\n---\n\n### PoC\n\n**Requirements:**\n- elFinder 2.1.69 deployed under Apache/Nginx (PHP-FPM or mod_php)\n- Connector configured with `uploadDeny = ['text/x-php']` and `uploadAllow` including `application/zip`\n- `files/` directory served under a public web path\n\n**Step 1 — Confirm direct upload is blocked**\nOpen elFinder in a browser and click the **Upload** button.  \nSelect `hello.phtml` (content: `\u003c?php phpinfo(); ?\u003e`).  \n→ Upload is rejected with: *\"Upload file hello.phtml: File type not allowed (text/x-php)\"*\n\u003cimg width=\"1061\" height=\"408\" alt=\"1\" src=\"https://github.com/user-attachments/assets/22f833d9-7d2a-4197-85c2-3b0eb19ecfbc\" /\u003e\n\n\n**Step 2 — Upload a ZIP containing the payload**\nCreate `bypass.zip` containing `hello.phtml`.  \nUpload `bypass.zip` via the **Upload** button.  \n→ ZIP is accepted (MIME: `application/zip` ∈ `uploadAllow`).\n\u003cimg width=\"886\" height=\"320\" alt=\"2\" src=\"https://github.com/user-attachments/assets/30c3498f-91f4-45cf-8c2b-cc806716e3a4\" /\u003e\n\n\n**Step 3 — Extract the ZIP**\nRight-click `bypass.zip` in the file list → **Extract files**.  \n→ `hello.phtml` appears in the file list without any error.  \n→ File is now present at `{files_dir}/hello.phtml` on the server.\n\u003cimg width=\"1123\" height=\"792\" alt=\"3\" src=\"https://github.com/user-attachments/assets/49e7db8e-566c-4653-a57f-e80fb31ea61d\" /\u003e\n\n\n**Step 4 — Execute the extracted PHP file**\n\nNavigate to:\n```\nhttp://\u003ctarget\u003e/elFinder/files/hello.phtml\n```\n→ Apache processes the file as PHP and renders the full `phpinfo()` output, confirming Remote Code Execution.\n\n---\n\u003cimg width=\"1059\" height=\"739\" alt=\"4\" src=\"https://github.com/user-attachments/assets/ad85fdf7-bdc7-4514-bdec-e45cfb2e2bd3\" /\u003e\n\n\n\n### Impact\n\nAny 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.\n\n**Concrete impact:**\n- Arbitrary PHP code execution on the web server\n- Full server environment disclosure via `phpinfo()` (paths, PHP version, loaded modules, environment variables)\n- Potential access to server filesystem, database credentials, and internal network services\n- Complete compromise of the web application if an attacker substitutes `phpinfo()` with a web shell (e.g., `\u003c?php system($_GET['cmd']); ?\u003e`)\n\n**Extensions confirmed executable on Apache (default config):**\nphtml, phar, php5, php3\n\n**Recommended fix:**\n\nApply `mimeTypeNormalize()` inside `checkExtractItems()` so that the full MIME pipeline is used consistently:\n\n```php\n// elFinderVolumeDriver.class.php, line 7110\n// Before (vulnerable):\n$mimeByName = elFinderVolumeDriver::mimetypeInternalDetect($name)\n\n// After (fixed):\n$mimeByName = $this-\u003emimeTypeNormalize(\n    elFinderVolumeDriver::mimetypeInternalDetect($name),\n    $name,\n    pathinfo($name, PATHINFO_EXTENSION)\n)\n```\n\n---\n\n---","status":"published","published":"2026-09-02T14:37:54Z","modified":"2026-09-02T20:21:32Z","cvss":[{"version":"3.1","score":8.1,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"high"}],"cwes":["CWE-434"],"updated_at":"2026-11-02T14:41:11.621873Z"}],"nvd":[{"id":"CVE-2026-81891","description":"elFinder is an open-source file manager for web, written in JavaScript using jQuery UI. Prior to 2.1.70, checkExtractItems() in php/elFinderVolumeDriver.class.php calls mimetypeInternalDetect() without passing the result through mimeTypeNormalize(). Because the .phtml, .phar, .php5, and .php3 extensions are absent from mime.types, the staticMimeMap entries that map them to text/x-php are not applied, and allowPutMime() permits extraction even when uploadDeny blocks text/x-php. An attacker with ZIP upload permission can extract PHP-executable files into a web-accessible files/ directory and achieve remote code execution when the server executes those extensions. This issue is fixed in version 2.1.70.","status":"published","published":"2026-08-31T21:17:52.757Z","modified":"2026-09-09T21:09:13.08Z","cvss":[{"version":"3.1","score":8.1,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"high","assessor":"secondary"}],"cwes":["CWE-434"],"updated_at":"2026-11-02T14:12:42.691315Z"}],"osv":[{"id":"CVE-2026-81891","title":"elFinder: ZIP extraction bypasses uploadDeny MIME filter allowing PHP file upload (RCE)","description":"elFinder is an open-source file manager for web, written in JavaScript using jQuery UI. Prior to 2.1.70, checkExtractItems() in php/elFinderVolumeDriver.class.php calls mimetypeInternalDetect() without passing the result through mimeTypeNormalize(). Because the .phtml, .phar, .php5, and .php3 extensions are absent from mime.types, the staticMimeMap entries that map them to text/x-php are not applied, and allowPutMime() permits extraction even when uploadDeny blocks text/x-php. An attacker with ZIP upload permission can extract PHP-executable files into a web-accessible files/ directory and achieve remote code execution when the server executes those extensions. This issue is fixed in version 2.1.70.","status":"published","published":"2026-08-31T20:33:22.283Z","modified":"2026-10-28T02:30:45.386194609Z","cvss":[{"version":"3.1","score":8.1,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"high"}],"cwes":["CWE-434"],"updated_at":"2026-11-02T15:45:18.131258Z"},{"id":"GHSA-gxmj-r5rf-ggwq","title":"elFinder: ZIP extraction bypasses uploadDeny MIME filter allowing PHP file upload (RCE)","description":"### Summary\n\nelFinder 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.\n\n---\n\n### Details\n\nelFinder's MIME validation pipeline for **direct uploads** (`upload` command) is:\n\n```\nmimetype()\n  └─ mimetypeInternalDetect()   // stage 1: extension → MIME via mime.types\n  └─ mimeTypeNormalize()        // stage 2: apply staticMimeMap\n       phtml:* → text/x-php\n       phar:*  → text/x-php\n       php5:*  → text/x-php\n  └─ allowPutMime()             // blocked: text/x-php ∈ uploadDeny\n```\n\nThe `extract` command (`checkExtractItems()` in `elFinderVolumeDriver.class.php`, line 7110) uses a **shortened** pipeline:\n\n```php\n// line 7110 — stage 2 (mimeTypeNormalize) is never called\nif ($chkMime\n    \u0026\u0026 ($mimeByName = elFinderVolumeDriver::mimetypeInternalDetect($name))\n    \u0026\u0026 !$this-\u003eallowPutMime($mimeByName)) {\n```\n\nBecause `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.\n\n**Affected extensions confirmed:** `.phtml`, `.phar`, `.php5`, `.php3`  \n**Not bypassed:** `.php` (present in `mime.types`, detected as `text/x-php` in stage 1)\n\n---\n\n### PoC\n\n**Requirements:**\n- elFinder 2.1.69 deployed under Apache/Nginx (PHP-FPM or mod_php)\n- Connector configured with `uploadDeny = ['text/x-php']` and `uploadAllow` including `application/zip`\n- `files/` directory served under a public web path\n\n**Step 1 — Confirm direct upload is blocked**\nOpen elFinder in a browser and click the **Upload** button.  \nSelect `hello.phtml` (content: `\u003c?php phpinfo(); ?\u003e`).  \n→ Upload is rejected with: *\"Upload file hello.phtml: File type not allowed (text/x-php)\"*\n\u003cimg width=\"1061\" height=\"408\" alt=\"1\" src=\"https://github.com/user-attachments/assets/22f833d9-7d2a-4197-85c2-3b0eb19ecfbc\" /\u003e\n\n\n**Step 2 — Upload a ZIP containing the payload**\nCreate `bypass.zip` containing `hello.phtml`.  \nUpload `bypass.zip` via the **Upload** button.  \n→ ZIP is accepted (MIME: `application/zip` ∈ `uploadAllow`).\n\u003cimg width=\"886\" height=\"320\" alt=\"2\" src=\"https://github.com/user-attachments/assets/30c3498f-91f4-45cf-8c2b-cc806716e3a4\" /\u003e\n\n\n**Step 3 — Extract the ZIP**\nRight-click `bypass.zip` in the file list → **Extract files**.  \n→ `hello.phtml` appears in the file list without any error.  \n→ File is now present at `{files_dir}/hello.phtml` on the server.\n\u003cimg width=\"1123\" height=\"792\" alt=\"3\" src=\"https://github.com/user-attachments/assets/49e7db8e-566c-4653-a57f-e80fb31ea61d\" /\u003e\n\n\n**Step 4 — Execute the extracted PHP file**\n\nNavigate to:\n```\nhttp://\u003ctarget\u003e/elFinder/files/hello.phtml\n```\n→ Apache processes the file as PHP and renders the full `phpinfo()` output, confirming Remote Code Execution.\n\n---\n\u003cimg width=\"1059\" height=\"739\" alt=\"4\" src=\"https://github.com/user-attachments/assets/ad85fdf7-bdc7-4514-bdec-e45cfb2e2bd3\" /\u003e\n\n\n\n### Impact\n\nAny 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.\n\n**Concrete impact:**\n- Arbitrary PHP code execution on the web server\n- Full server environment disclosure via `phpinfo()` (paths, PHP version, loaded modules, environment variables)\n- Potential access to server filesystem, database credentials, and internal network services\n- Complete compromise of the web application if an attacker substitutes `phpinfo()` with a web shell (e.g., `\u003c?php system($_GET['cmd']); ?\u003e`)\n\n**Extensions confirmed executable on Apache (default config):**\nphtml, phar, php5, php3\n\n**Recommended fix:**\n\nApply `mimeTypeNormalize()` inside `checkExtractItems()` so that the full MIME pipeline is used consistently:\n\n```php\n// elFinderVolumeDriver.class.php, line 7110\n// Before (vulnerable):\n$mimeByName = elFinderVolumeDriver::mimetypeInternalDetect($name)\n\n// After (fixed):\n$mimeByName = $this-\u003emimeTypeNormalize(\n    elFinderVolumeDriver::mimetypeInternalDetect($name),\n    $name,\n    pathinfo($name, PATHINFO_EXTENSION)\n)\n```\n\n---\n\n---","status":"published","published":"2026-09-02T14:37:54Z","modified":"2026-09-02T20:30:04.228208839Z","cvss":[{"version":"3.1","score":8.1,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"high"}],"cwes":["CWE-434"],"updated_at":"2026-11-02T15:46:48.546324Z"}]}}
