Mitigates the PolyShell vulnerability — an unrestricted file upload in the Magento REST API that allows attackers to upload executable files via cart item custom option file uploads.
This package has been deprecated and abandoned in favor of aregowe/magento2-module-polyshell-protection.
That module integrates all of this module's protection and extends it significantly with:
- Polyglot file scanning (detects valid images with embedded PHP)
- No-extension and double-extension attack detection
- Multi-pass URL decoding and obfuscation normalization
- Known attack filename/pattern matching
- Request path blocking at the FrontController and
pub/get.phplevel - Controller-level upload blocking for customer attribute and file upload endpoints
- A kill switch blocking all custom option file uploads via the Webapi File Processor
If you currently have this module installed, migrate with:
bin/magento module:disable MarkShust_PolyshellPatch
bin/magento setup:upgrade
composer require aregowe/magento2-module-polyshell-protection
bin/magento module:enable Aregowe_PolyShellProtection
bin/magento setup:upgrade
bin/magento cache:flushThe replacement package includes a Composer replace directive for markshust/magento2-module-polyshell-patch, so Composer will handle the transition automatically.
The following documentation is preserved for reference only. This module is no longer maintained. If you choose to use it anyway, it will still block the basic exploit, but the replacement module above provides far more comprehensive protection.
Two plugins enforce an image-only extension allowlist (jpg, jpeg, gif, png):
- ImageContentValidatorExtension — rejects filenames with non-image extensions before the file is written to disk.
- ImageProcessorRestrictExtensions — calls
setAllowedExtensions()on theUploaderso the framework's own extension check blocks dangerous files as a second layer.
composer require markshust/magento2-module-polyshell-patch
bin/magento module:enable MarkShust_PolyshellPatch
bin/magento setup:upgrade
bin/magento cache:flushThe module blocks uploads at the application layer, but defense-in-depth requires blocking execution/access at the web server level too. Apply the appropriate config below.
Add this before any location ~ \.php$ block to prevent it from taking priority:
location ^~ /media/custom_options/ {
deny all;
return 403;
}Verify the order matters — nginx processes ^~ prefix matches before regex matches, so this ensures .php files in this directory are never passed to FastCGI.
Reload after applying:
nginx -t && nginx -s reloadVerify that pub/media/custom_options/.htaccess exists and contains:
<IfVersion < 2.4>
order deny,allow
deny from all
</IfVersion>
<IfVersion >= 2.4>
Require all denied
</IfVersion>Also confirm that AllowOverride All is set for your document root so .htaccess files are honored.
Check whether any files have already been uploaded to the custom_options directory:
find pub/media/custom_options/ -type f ! -name '.htaccess'If any files are found (especially .php, .phtml, or .phar), investigate immediately — they may be webshells.
This module is an interim hotfix. Remove it once Adobe backports the official patch to production Magento versions (2.4.8-p4 or later). To remove:
If you have installed it manually:
bin/magento module:disable MarkShust_PolyshellPatch
bin/magento setup:upgrade
rm -rf app/code/MarkShust/PolyshellPatch
bin/magento cache:flushIf you have installed it by composer:
bin/magento module:disable MarkShust_PolyshellPatch
bin/magento setup:upgrade
composer remove markshust/magento2-module-polyshell-patch
bin/magento cache:flushAdobe's official fix spans 18 files (+997 lines) across Magento_Catalog, Magento_Quote, and the framework. It introduces a new ImageContentProcessor, a CartItemValidatorChain at the Repository layer, an ImageContentUploaderInterface, and API-scoped DI configuration.
We intentionally did not replicate that approach because:
- It modifies core module internals. The official patch alters constructors, adds dependencies to
CustomOptionProcessorandRepository, and introduces new interfaces — changes that are tightly coupled to specific Magento versions and could conflict with the official patch when it ships. - A minimal allowlist is sufficient to block the exploit. The vulnerability is that any file extension is accepted. Our two plugins enforce a strict image-only allowlist (
jpg,jpeg,gif,png) at both the validator and uploader level. This is actually stricter than the official fix, which uses a denylist approach (NotProtectedExtension) that rejects known-dangerous extensions. - Lower risk of side effects. A small, self-contained module with two plugins is easy to audit, test, and remove cleanly — which is exactly what you want from a temporary hotfix.
- Sansec: Magento PolyShell
- Adobe official fix (commit)
- Adobe Security Bulletin: APSB25-94
- Patched in Magento 2.4.9-alpha3+ (pre-release only, no production patch available)
This module is sponsored by M.academy, the simplest way to learn Magento.