Magento and Adobe Commerce PolyShell RCE Exploited in the Wild (CVE-2026-48356)
PolyShell (CVE-2026-48356) is an unauthenticated file upload in Magento's REST API, mass-exploited since March 2026; Adobe's July 2026 patch releases fix it.
TL;DR
- CVE-2026-48356, named PolyShell by the Sansec research team that found it, is an unrestricted file upload in the Magento and Adobe Commerce REST API: an unauthenticated caller can write an executable file to the server through the guest-cart item routes. Adobe's CVE record rates it CVSS v3.1 9.3 (
AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N). - Every production branch is affected: Adobe Commerce 2.4.4 through 2.4.9 and Magento Open Source 2.4.6 through 2.4.9 at their pre-July-2026 patch levels, plus Commerce B2B and Adobe Commerce Events. The July 2026 patch releases (
2.4.9-2026-jul,2.4.8-2026-jul, and so on) are the fix for supported lines. - It is exploited in the wild at scale. Sansec recorded automated mass scanning from March 19, 2026, malicious PHP uploaded to 82 percent of the stores it monitors by April 14, and estimates 471 of the 953 stores in the follow-on loader campaign were injected through PolyShell. CISA added CVE-2026-48356 to its Known Exploited Vulnerabilities catalog on October 27, 2026, with a federal deadline of November 10, 2026.
- Apply the July 2026 patch release for your branch now. If you cannot patch today, block web access to
pub/media/custom_options/and filter the guest-cart API routes at a WAF, then hunt for uploaded shells and theaccesson.phpbackdoor with the checks below.
Am I affected?
You are affected if you run Adobe Commerce, Magento Open Source, Adobe Commerce B2B or Adobe Commerce Events at one of the versions in the table below, and your REST API (including the guest-cart routes) is reachable over the network.
Adobe's CVE record and Sansec disagree on 2.4.9 general availability: the record marks 2.4.9 as affected up to the July patch, while Sansec reports the 2.4.9 general availability release of May 12, 2026 already carries the fix.
Sansec adds that the July releases backport the fix to the older supported lines. Verify where your build sits before you decide you are safe.
| Branch | Affected versions | Fixed version |
|---|---|---|
| Adobe Commerce 2.4.9 line | 2.4.9 at pre-July-2026 patch level | 2.4.9-2026-jul per Adobe's CVE record; 2.4.9 GA (May 12, 2026) per Sansec |
| Adobe Commerce 2.4.8 line | 2.4.8-p5 and earlier | 2.4.8-2026-jul |
| Adobe Commerce 2.4.7 line | 2.4.7-p10 and earlier | 2.4.7-2026-jul |
| Adobe Commerce 2.4.6 line | 2.4.6-p15 and earlier | 2.4.6-2026-jul |
| Adobe Commerce 2.4.5 line | 2.4.5-p17 and earlier | 2.4.5-2026-jul |
| Adobe Commerce 2.4.4 line | 2.4.4-p18 and earlier | 2.4.4-2026-jul |
| Adobe Commerce B2B | 1.5.3; 1.5.2-p5 and earlier; 1.4.2-p10 and earlier; 1.3.4-p17 and earlier; 1.3.3-p18 and earlier | 1.5.3-2026-jul, 1.5.2-2026-jul, 1.4.2-2026-jul, 1.3.4-2026-jul, 1.3.3-2026-jul |
| Magento Open Source 2.4.9 line | 2.4.9 at pre-July-2026 patch level | 2.4.9-2026-jul per Adobe's CVE record; 2.4.9 GA (May 12, 2026) per Sansec |
| Magento Open Source 2.4.8 line | 2.4.8-p5 and earlier | 2.4.8-2026-jul |
| Magento Open Source 2.4.7 line | 2.4.7-p10 and earlier | 2.4.7-2026-jul |
| Magento Open Source 2.4.6 line | 2.4.6-p15 and earlier | 2.4.6-2026-jul |
| Adobe Commerce Events | 1.20.0 and earlier | 1.21.0 |
Check the version on the running instance, not a fresh image:
# From the Magento root directory
php bin/magento --version
# From the composer lock file
grep -A1 '"name": "magento/product-community-edition"' composer.lock # Open Source
grep -A1 '"name": "magento/product-enterprise-edition"' composer.lock # Adobe Commerce
# In a container
docker exec <container> php bin/magento --version
How do I fix it?
Install the July 2026 patch release (APSB26-73) for your branch through your usual Composer or command-line upgrade path, and verify php bin/magento --version reports the fixed level afterwards. Adobe's bulletin is the authoritative list of fixed versions. Sansec attributes the July 2026 backports to APSB26-73 and the 2.4.9 general availability release to the preceding APSB25-94 fix in the 2.4.9 pre-release branch.
If you cannot patch today, two mitigations cut the risk. Both are adapted from Sansec's advisory:
- Block web access to the upload directory. For nginx, add this block inside the server configuration before any
\.php$location block, so the PHP handler cannot take precedence:
location ~* ^/pub/media/custom_options/ {
return 403;
}
For Apache, verify that pub/media/custom_options/.htaccess exists and contains:
<IfModule mod_php.c>
php_flag engine 0
</IfModule>
Deny from all
Sansec notes that most stores use their hosting provider's custom web server configuration rather than Adobe's sample. - Block the guest-cart API routes at a WAF. This is the only control that stops the upload itself, since directory blocks leave the write path open.
Limits: blocking access does not block uploads. Attackers can still write files to disk through the API, and a later configuration change, migration or web server swap can make them executable. Even on configurations where PHP execution in the upload directory is blocked, the stored-XSS variant of this flaw (file served as content) remains, per Sansec's version analysis.
What is the root cause?
Magento's REST API writes a file from a cart-item request to disk without validating the option, the option type or the file extension. Sansec's technical analysis, published on March 17, 2026, describes the mechanism: when a product option has type file, Magento processes an embedded file_info object containing base64-encoded file data, a MIME type, and a filename, and writes the file to pub/media/custom_options/quote/ on the server.
Three checks are missing, in Sansec's analysis:
- No option ID validation. The submitted option ID is never verified against the product's actual options.
- No option type gating. The file upload logic triggers regardless of whether the product actually has a file-type option.
- No file extension restriction. Extensions like
.php,.phtmland.pharare not blocked; the only validation is an image header check (getimagesizefromstring), which a polyglot file that is both a valid image and executable PHP passes trivially.
The most dangerous endpoints are the anonymous guest cart routes, which need no credentials:
| Method | Endpoint | Authentication |
|---|---|---|
| POST | /V1/guest-carts/:cartId/items |
None |
| PUT | /V1/guest-carts/:cartId/items/:itemId |
None |
GraphQL mutations use a different code path and are not vulnerable, per Sansec. Adobe has not published an official patch diff or fix analysis for CVE-2026-48356, so the exact patch logic cannot be quoted here; the fix shipped first in the 2.4.9 pre-release branch (APSB25-94), then in the 2.4.9 general availability release of May 12, 2026, and in the July 2026 backports for every supported line.
How is it exploited?
The attack path, from Sansec's published payload analysis, runs from a single unauthenticated request to a persistent backdoor:
- The attacker sends a POST to
/V1/guest-carts/:cartId/itemswith afile_infoobject whose base64 payload is a polyglot: a valid GIF or PNG image that also embeds executable PHP, which satisfies the image header check. - The file is written under
pub/media/custom_options/quote/, commonly with a filename likeindex.phpor the option ID prepended, such as780index.php. - On configurations that hand
.phpfiles in or below the upload directory to the PHP handler, the uploaded file executes as the web server user when requested. Sansec's version analysis ties this to the stock nginx sample configuration shipped with Magento 2.0.0 to 2.2.x (via theindex.phpfilename), any Magento version behind a non-stock nginx configuration passing all.phpto fastcgi, and Apache on Magento releases before 2.3.5 withoutphp_flag engine 0. - The most common payload Sansec captured is a GIF89a polyglot
index.phpweb shell: it verifies the cookiedagainst the hardcoded hasha17028468cb2a870d460676d6d6da3ad63706778e3, then executes arbitrary PHP viaeval(base64_decode()), and includes a file upload function triggered by$_POST["up"]. A second variant useshash_equals()with the hardcoded MD54009d3fa8132195a2dab4dfa3affc8d2and passes commands straight tosystem(). - For persistence, the attackers deploy a secondary backdoor named
accesson.php, placed at<top-level directory>/assets/images/accesson.phpin every top-level directory they can write to. Sansec lists ten such paths on one store, includingvar/assets/images/accesson.php,app/assets/images/accesson.php,vendor/assets/images/accesson.phpandpub/assets/images/accesson.php. It prints the beacon8194460so the operator can find live shells at scale, and otherwise works like the first payload. - Finally, the attackers inject an obfuscated JavaScript loader into CMS pages or blocks, which serves further payloads to shoppers' browsers.
/V1/guest-carts/:cartId/items"] --> B["file_info with base64
polyglot (image + PHP)"] B --> C["Only image header checked,
no extension or option check"] C --> D["File written to
pub/media/custom_options/quote/"] D --> E["Web server executes .php
on vulnerable configurations"] E --> F["GIF89a web shell runs
eval(base64_decode())"] F --> G["accesson.php backdoor +
CMS-block JS loader"] G --> H["Shopper browsers fetch
attacker-controlled payloads"]
PolyShell filenames observed in the wild include index.php, json-shell.php, bypass.phtml, c.php, r.php, rce.php, static.php, test.php, blocked-json.php, bypass-async.php, urlencode-shell.php and xx_malicious_file.php, with Unicode obfuscation such as \u0062\u0079\u0070\u0061\u0073\u0073.\u0070\u0068\u0070 (decodes to bypass.php) also seen.
The scale was immediate. Sansec's telemetry shows 23 percent of its protected stores targeted by March 23, 2026, and 79.5 percent by March 30. Malicious PHP had been uploaded to 56.7 percent of stores by March 24 and 82 percent by April 14. All of this came before the first general-availability fix existed.
What can an attacker do?
The impact splits by web server configuration, and both branches are bad. Where PHP executes, the attacker runs code as the web server user: web shells, full control of the store, and the ability to read and rewrite the database. Sansec observed exactly that in the wild, with webshells disguised as PNG images sitting in pub/media/custom_options/quote/ next to a CMS-block loader. Where execution is blocked, the uploaded file still sits on disk (a future configuration change can expose it), and the stored-XSS variant can take over an administrator session instead.
Scoring note: Adobe's CVE record rates the issue CVSS v3.1 9.3 with scope changed and notes exploitation "could result in arbitrary code execution in the context of the current user, potentially gaining elevated access or control over the victim's account or session". The record's UI:R vector scores the paths that need a victim to visit crafted content; the guest-cart upload itself requires no credentials and no user interaction.
The conditions the attack needs:
- A reachable REST API on an affected version, including the anonymous guest-cart routes.
- For code execution rather than just file placement, a web server configuration that executes PHP files from the upload path. Sansec found many stores expose files in the upload directory.
- Nothing else: no account, no authentication, no user action for the upload step.
Is the fix verified?
No. Adobe has not published an official patch diff or fix analysis, so the fix cannot be checked against a diff. What is public: the fix first landed in the 2.4.9 pre-release branch under APSB25-94 (October 14, 2025, fixed in 2.4.9-alpha3), shipped in the 2.4.9 general availability release on May 12, 2026, and was backported to every supported release line in the July 2026 patch releases (APSB26-73), per Sansec's advisory and Adobe's CVE record.
A complete fix for the behavior Sansec described has to close all three gaps: validate the submitted option ID against the product, only accept file_info when the product actually declares a file-type option, and restrict which filenames and extensions can be written.
Sansec's telemetry peaked at 82 percent of monitored stores with malicious uploads by April 14, before the May 12 general availability release and before older lines had any backport. The KEV listing on October 27 shows the unpatched population is still being attacked.
How do I check if I was compromised?
These checks and indicators are adapted from Sansec's advisory. Run them from the Magento root directory on every store at or below the affected levels:
# Executable files in the custom options upload directory are a strong indicator.
find pub/media/custom_options/ -type f \( -name '*.php' -o -name '*.phtml' -o -name '*.phar' \)
# Stores that never offered file-type product options: any file other than
# .htaccess is suspicious. Legitimate customer file-option uploads land under
# pub/media/custom_options/quote/ and order/, so skip this on stores that use them.
find pub/media/custom_options/ -type f ! -name '.htaccess'
# The post-exploitation backdoor, placed under assets/images/ in top-level directories.
find . -name 'accesson.php' -type f
- Any
.php,.phtmlor.pharfile underpub/media/custom_options/is a strong indicator of compromise. Inspect GIF and PNG files there too: polyglot shells carry aGIF89aor PNG header with PHP inside. - Search CMS pages and static blocks (the
cms_blockandcms_pagetables) for the campaign's loader domains (table below). Sansec's earlier PolyShell-era research also listsjslibrary[.]netandcanevaslab[.]com. - Audit admin accounts: Sansec documented one fully patched 2.4.7-p10 store whose only sign of compromise was a rogue administrator account used to inject the loader. That case was not PolyShell, but it is part of the same campaign.
- Sansec's advisory lists more than 50 source IPs observed in PolyShell scanning, from March 2026 onward, for perimeter log review.
| Loader domain | First seen |
|---|---|
manulfie[.]click |
July 2025 |
neswnsssn[.]click |
December 2025 |
lanhd6549tdhse[.]top |
March 2026 |
additionalver[.]com |
June 2026 |
deepveindrilling[.]com |
Registered October 6, 2026; in the CMS blocks of 83 stores by October 24 |
Timeline
- 2025-07: the loader campaign begins; 953 stores, most on Magento, are infected over its course (Sansec, published October 2026).
- 2025-10-14: Adobe's APSB25-94 update ships 2.4.9-alpha3, the 2.4.9 pre-release where Sansec says the fix first landed (APSB25-94, Sansec).
- 2026-03-16: first PolyShell probing observed at 12:00 UTC; Sansec adds Shield protection the same day (Sansec).
- 2026-03-17: Sansec publishes its public warning and technical analysis (Sansec).
- 2026-03-19: automated mass scanning begins; more than 50 scanner IPs follow (Sansec).
- 2026-03-23: 23 percent of Sansec-protected stores targeted.
- 2026-03-24: malicious PHP uploaded to 56.7 percent of stores (Sansec).
- 2026-03-30: 79.5 percent of stores targeted (Sansec).
- 2026-04-14: malicious PHP uploaded to 82 percent of stores (Sansec).
- 2026-05-12: Adobe releases Magento 2.4.9 with the fix; no backport yet for older supported lines (Sansec).
- 2026-07-14: Adobe's CVE record is published and the July 2026 patch releases backport the fix to supported lines (CVE record, APSB26-73).
- 2026-10-06:
deepveindrilling[.]comregistered; live October 7; in 83 stores' CMS blocks by October 24 (Sansec). - 2026-10-27: CISA adds CVE-2026-48356 to the Known Exploited Vulnerabilities catalog; federal deadline November 10, 2026 (CISA KEV).
- 2026-10-28: this post.
The gap between the public warning and the KEV listing runs 224 days, and the fix only reached older supported lines 119 days after the warning.
FAQ
Is PolyShell the same CVE as the Sansec loader campaign?
They are related but distinct. CVE-2026-48356 (PolyShell) is the upload vulnerability in the REST API. The loader campaign Sansec tracks (953 stores, five domains since July 2025) is the criminal operation that uses PolyShell as one of its entry vectors: Sansec estimates 471 stores were injected through PolyShell and another 102 through PolyShell or the earlier SessionReaper flaw (CVE-2025-54236). At least one store was entered through a rogue admin account instead.
My web server blocks PHP in the upload directory. Am I safe?
Not fully. Blocking execution stops the remote-code-execution variant, but the API still writes attacker files to disk, Sansec's stored-XSS variant remains on some configurations, and a future server migration or configuration change can turn the parked files into live shells. Patching is the complete remediation; the web-server blocks are a stopgap.
Why did CISA only add a July-fixed flaw to KEV in October?
Because exploitation is ongoing and the unpatched population is still large. The flaw was mass-scanned within days of the March disclosure, the fix only reached older supported lines in July, and Sansec was still finding fresh loader domains in store CMS blocks in October. CISA's KEV entry, dated October 27, 2026, carries a federal remediation deadline of November 10, 2026.
Do I need a WAF rule if I patch?
Patching removes the vulnerability, so a WAF rule is optional afterwards. Before patching, Sansec is explicit that only a WAF rule blocking the vulnerable API call stops uploads, because directory blocks leave the write path open. Sansec's advisory also notes that, at its last update, Cloudflare had not published a WAF rule covering PolyShell, so do not rely on a cloud WAF to block PolyShell until you have confirmed it ships a matching rule.
Does this affect Magento Open Source or only Adobe Commerce?
Both. Adobe's CVE record lists affected versions of Adobe Commerce, Adobe Commerce B2B, Magento Open Source (2.4.6 through 2.4.9 lines) and Adobe Commerce Events, with the July 2026 patch releases as the fix for each.
Find exposed Adobe Commerce and Magento stores with Ostorlab
Run an Ostorlab web scan on every storefront: it identifies the Adobe Commerce or Magento version and patch level each store runs and whether the guest-cart upload routes are exposed, so you can confirm each one runs a fixed release from the table above before the November 10 KEV deadline.
References
- CISA KEV entry for CVE-2026-48356, added October 27, 2026, due November 10, 2026: https://www.cisa.gov/known-exploited-vulnerabilities-catalog (checked October 28, 2026)
- CVE record, CVSS v3.1 9.3, affected and fixed version matrix: https://cveawg.mitre.org/api/cve/CVE-2026-48356 (checked October 28, 2026)
- Adobe security bulletin APSB26-73 (the July 2026 patch releases): https://helpx.adobe.com/security/products/magento/apsb26-73.html
- Sansec, "PolyShell: unrestricted file upload in Magento and Adobe Commerce", March 17, 2026, with updates through October 2026 (technical analysis, payload analysis, scanner IPs, mitigation): https://sansec.io/research/magento-polyshell (checked October 28, 2026)
- Sansec, "deepveindrilling.com: Magento CMS block loader hits 953 stores", October 2026 (campaign attribution: 471 via PolyShell, 102 via PolyShell or SessionReaper, 83 stores with the October loader domain): https://sansec.io/research/magento-cms-block-loader-deepveindrilling (checked October 28, 2026)
- Sansec, "SessionReaper, unauthenticated RCE in Magento & Adobe Commerce (CVE-2025-54236)" for the companion flaw: https://sansec.io/research/sessionreaper
- The Hacker News, "Adobe Commerce PolyShell Attacks Breach Hundreds of Stores as Brotli Exploit Traffic Emerges", October 28, 2026: https://thehackernews.com/2026/10/adobe-commerce-polyshell-attacks-breach.html
- The Hacker News, "Hackers Infect 953 Online Stores With Scanner-Evading JavaScript, Mostly on Magento", October 26, 2026: https://thehackernews.com/2026/10/hackers-infect-953-online-stores-with.html
- The Hacker News, "Magento PolyShell Flaw Enables Unauthenticated Uploads, RCE and Account Takeover", March 20, 2026, updated March 23 with the active-exploitation record: https://thehackernews.com/2026/03/magento-polyshell-flaw-enables.html