PolyShell: Magento file-upload flaw hit 56% of vulnerable stores in days

Sansec saw PolyShell attacks on 56.7% of vulnerable Magento stores days after disclosure. How the upload bug works and the nginx/Apache rules that block it.

TechLogHub Engineering Team
March 25, 2026
3 min read
0 views

Share Article

PolyShell Attacks Target 56 % of All Vulnerable Magento Stores

PolyShell is an unauthenticated file-upload bug in Magento Open Source and Adobe Commerce 2.x. In March 2026, within days of disclosure, Sansec saw attacks on 56.7% of the stores it considered vulnerable. Whether an upload becomes remote code execution or just stored XSS depends almost entirely on your web server config, which makes this as much an ops problem as an application one.

What happened

E-commerce security firm Sansec published its PolyShell research on 17 March 2026. The bug sits in Magento's REST API, which accepts file uploads as part of a cart item's custom options. Mass exploitation began on 19 March, about two days after disclosure. Sansec's reporting cited by The Hacker News puts the first active exploitation on 16 March. By 25 March, BleepingComputer reported, Sansec had seen PolyShell attacks on 56.7% of all vulnerable stores. The Sansec research page has since been updated with higher figures.

Adobe had already changed the upload handling in the 2.4.9 pre-release branch, referenced in bulletin APSB25-94, and shipped it in 2.4.9-beta1 on 10 March 2026. At the time of the attacks no isolated patch existed for production 2.4.x releases, and Adobe did not give BleepingComputer a timeline. Sansec also reported a new skimmer in some suspected PolyShell intrusions. It loads its second stage over WebRTC, which uses DTLS-encrypted UDP, so it can slip past CSP connect-src rules and HTTP monitoring.

Who is affected

  • Magento Open Source and Adobe Commerce 2.x stable releases without the 2.4.9 change or an equivalent mitigation.
  • Stores whose web server serves or executes files under pub/media/custom_options/. Adobe's sample nginx and Apache configs block this, but many stores run host-supplied configs that do not.
  • Agencies and hosts that maintain many Magento installs from a shared config template, because one weak template exposes every store built on it.

What it means for developers and engineering teams

The attack path is simple. An unauthenticated POST to /rest/default/V1/guest-carts/:cartId/items can include a file_info object (base64 data, MIME type, filename) inside custom_options. Assetnote's analysis says the product doesn't even need a file-type option configured. Magento writes the file to pub/media/custom_options/quote/<a>/<b>/<name>. A polyglot file passes image checks and still works as a script.

What happens next depends on the server:

  • Apache: if pub/media/custom_options/.htaccess is missing, the file can be served (stored XSS). If pub/media/.htaccess with php_flag engine 0 is also missing, a .php upload executes (RCE). Renaming AccessFileName without renaming those files has the same effect.
  • nginx: removing Adobe's deny all for custom_options enables XSS. Removing the rule that stops PHP execution under /media enables RCE.

The general lesson applies far beyond Magento. Never let a user-upload directory be both web-reachable and executable, and don't rely on application-level MIME checks alone. Polyglots are built to pass them.

What to do now

  1. Upgrade to a release that contains the fix. Adobe moved it into the 2.4.9 line, so check Adobe's current security bulletins for your branch.
  2. Block the directory at the web server. Apache:
    <LocationMatch "^/media/custom_options/">
        Require all denied
    </LocationMatch>
    nginx (inside the Magento server block):
    location ^~ /media/custom_options/ { deny all; }
    location ~ ^/media/.*\.php$ { deny all; }
  3. Consider an interim module. Mark Shust's community patch has been superseded by aregowe/magento2-module-polyshell-protection. Review the code before you install it.
  4. Hunt for uploads:
    find pub/media/custom_options/ -type f ! -name '.htaccess' -ls
    find . -name "accesson.php" -type f -ls
    Anything that isn't an expected image is suspect. Review .svg files carefully.
  5. Check logs for POST requests to /V1/guest-carts/*/items containing file_info, and compare source IPs with Sansec's published list.
  6. Look for skimmers in CMS blocks, theme JS and checkout templates, and monitor for unexpected WebRTC/UDP egress. Sansec's eComscan is one free option.
  7. If you find a webshell, rebuild. Patching does not remove persistence. Rotate admin, database and payment-gateway credentials.

Related on TechLogHub

  • Nginx vs Apache: how each one handles per-directory rules
  • XSS: what stored cross-site scripting allows
  • REST API: why unauthenticated endpoints need strict input rules

Sources

Stay Updated

Get the next deep dive in your inbox

Subscribe for product analysis, engineering explainers, and practical guides published on TechLogHub.

See what launched this week

One email a week: new and trending developer tools, fresh comparisons, and what shipped. Unsubscribe in one click.

PolyShell Magento Flaw: Mass Exploitation and Fixes | Polyshell Attacks Target 56 Of All Vulnerable Magento Stores | TechLogHub