Insights

    PolyShell (CVE-2026-48356): the Magento file upload flaw CISA now lists as exploited

    By Simon Bumford, Founder of EveryHost12 min read

    On 27 October 2026 the US Cybersecurity and Infrastructure Security Agency (CISA) added CVE-2026-48356 to its Known Exploited Vulnerabilities (KEV) catalog, "based on evidence of active exploitation". The flaw, which Sansec named PolyShell when they disclosed it in March, lets anyone upload a file to a Magento Open Source or Adobe Commerce store through the guest cart REST API, with no account and no login. Adobe fixed it in Magento 2.4.9, released on 12 May 2026, and for older lines in the July 2026 bulletin APSB26-73. Sansec have tracked attacks since 19 March 2026, including one wave that compromised 471 stores in a single hour. If your store is on 2.4.8 or earlier and has not had the July 2026 isolated patch, it is exposed today, and the files attackers upload may already be sitting on your server.

    How PolyShell gets in
    Guest cart APIno login neededImage checkgetimagesize: OKpub/mediacustom_options/GIF89a<?phpwebshellAPSB26-73 / 2.4.9option + extension checksupload refused

    CVE-2026-48356, CVSS 9.6, no login needed. On CISA's Known Exploited Vulnerabilities list since 27 October 2026.

    What PolyShell is

    Magento's REST API lets a shopper add a product to a cart with custom options. When an option is of type "file", the request carries a file_info object: the file's contents in base64, a MIME type and a filename. Magento decoded it and wrote the file to pub/media/custom_options/quote/. According to Sansec's analysis, three checks were missing. Magento did not confirm that the option ID belonged to the product, did not confirm that the option was actually a file-type option, and did not restrict the file extension, so .php, .phtml and .phar were all accepted. The only test was PHP's getimagesizefromstring, which passes any file that starts like an image. Hence the name: a polyglot file, a valid GIF or PNG header followed by PHP code, is an image to the check and a script to the web server.

    The two unauthenticated routes are POST /V1/guest-carts/{cartId}/items and PUT /V1/guest-carts/{cartId}/items/{itemId}. Sansec note that the GraphQL cart mutations use a different code path and are not affected.

    What happens after the upload depends on the web server. Sansec's advisory says the file runs as PHP on stock nginx configurations from Magento 2.0.0 to 2.2.x, on any nginx configuration that hands every .php request to PHP-FPM, and on Apache where pub/media/.htaccess lacks php_flag engine 0. That is remote code execution. Stock configurations for current versions serve media through get.php and refuse to execute PHP under pub/media, which turns the same upload into stored cross-site scripting, usable for account takeover. Either way the file lands on disk. A 400 Bad Request response to the upload request does not mean the file was refused: Magento can write the file before a later validation step fails, so always check the directory rather than the status code.

    Adobe classifies the flaw as CWE-434, Unrestricted Upload of File with Dangerous Type, Critical, with a CVSS 3.1 base score of 9.6. NVD scores the same vector at 9.3, the difference being the availability impact. Both agree on the part that matters: no privileges required.

    Timeline

    DateEvent
    17 March 2026Sansec publish the PolyShell advisory. The only fix at the time is in the 2.4.9 alpha.
    19 March 2026First attacks observed in the wild. Automated mass scanning begins.
    23 March 2026Mass scanning hits 23% of the stores Sansec protect.
    30 March 2026471 stores compromised in one hour. Attackers drop accesson.php backdoors and inject a JavaScript loader into CMS blocks.
    14 April 2026Sansec report malicious uploads on 82% of the stores they monitor.
    12 May 2026Adobe release Magento 2.4.9 with the fix. No backport yet for 2.4.8 and earlier.
    14 July 2026Adobe publish APSB26-73 with isolated patches for 2.4.4 to 2.4.9, and the CVE record is created.
    24 October 2026Sansec publish the deepveindrilling.com report: 953 stores hit by one loader campaign since July 2025, PolyShell among its entry routes.
    27 October 2026CISA add CVE-2026-48356 to the KEV catalog. Federal agencies have until 10 November 2026 to remediate.

    Two things stand out. The flaw was exploited for eight weeks before any production version carried the fix, and for four months before a patch existed for the versions most stores run. And the KEV listing arrived more than seven months after the first attacks. CISA's catalog confirms exploitation; it does not announce it. By the time a Magento flaw reaches KEV the question is no longer whether to patch, but whether you were already hit.

    Which Magento versions are affected

    Adobe's bulletin lists these versions as affected and fixed. The July fixes are isolated patches applied on top of the latest patch release of each line, not a new release and not a Composer update.

    ProductAffectedFixed
    Magento Open Source2.4.9; 2.4.8-p5 and earlier; 2.4.7-p10 and earlier; 2.4.6-p15 and earlier2.4.9-2026-jul, 2.4.8-2026-jul, 2.4.7-2026-jul, 2.4.6-2026-jul
    Adobe Commerce2.4.9; 2.4.8-p5 and earlier; 2.4.7-p10 and earlier; 2.4.6-p15 and earlier; 2.4.5-p17 and earlier; 2.4.4-p18 and earlierThe 2026-jul isolated patch for each of 2.4.9, 2.4.8, 2.4.7, 2.4.6, 2.4.5 and 2.4.4
    Adobe Commerce B2B1.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 earlierThe 2026-jul patch for each line

    On 2.4.9 the two sources differ in a way that matters for anyone who installed it from Composer in the summer. Sansec's timeline says the PolyShell fix shipped in 2.4.9 itself on 12 May. Adobe's bulletin lists 2.4.9 as affected by APSB26-73 as a whole, which covers 14 CVEs, and gives 2.4.9-2026-jul as the fixed version. The safe reading is that a base 2.4.9 has the PolyShell code fix but still needs the July isolated patch for the other thirteen flaws, including the CVSS 9.1 webhooks bug, and that the July patch is also what installs Adobe's patch-status tool. Apply it either way.

    For 2.4.8 and earlier there is no ambiguity: without the July 2026 isolated patch the store is vulnerable. The patch only applies on the exact latest patch release of the line, so a 2.4.7-p5 store has to reach 2.4.7-p10 before the July fix will go on, and a base 2.4.8 has to reach 2.4.8-p5. That upgrade step is where most delays come from. Our APSB26-73 guide has the download names and commands.

    What the CISA listing means

    KEV is CISA's list of vulnerabilities with evidence of real-world exploitation. Under Binding Operational Directive 26-04, US federal civilian agencies must remediate each entry by its due date, which for CVE-2026-48356 is 10 November 2026. Nothing in the directive binds a UK merchant. The value of the listing is the signal: CISA adds a CVE only when it has evidence of exploitation, and the catalog is the list that cyber insurers, PCI assessors and payment providers increasingly check.

    One oddity is worth knowing. Adobe's bulletin, last updated on 11 August 2026, still says Adobe "is not aware of any exploits in the wild" for the issues in APSB26-73. The exploitation evidence comes from Sansec's telemetry and the stores they have cleaned. CISA does not publish the evidence behind an entry, and it lists known ransomware use for this CVE as "unknown".

    PolyShell is the fifth Magento flaw on the KEV list in two and a half years: CosmicSting (CVE-2024-34102, added 17 July 2024), SessionReaper (CVE-2025-54236, 24 October 2025), StyleSmuggler (CVE-2026-75650, 8 September 2026), the APSB26-92 account takeover (CVE-2026-71362, 24 September 2026) and now PolyShell. For what each of those did, see our Magento upgrades and security patching page.

    What attackers do once the file is in

    Sansec's three reports describe a fully automated chain, and the same operator keeps reusing it.

    • The webshell. A GIF89a polyglot saved under a name such as 780index.php, the digits being the option ID the request used. It checks a cookie against a hard-coded hash and then runs whatever base64 payload it is sent. Other names seen: json-shell.php, bypass.phtml, c.php, r.php, rce.php, static.php, test.php, ato_poc.html.
    • The backdoor. The shell drops accesson.php into assets/images/ folders under many top-level directories (var/, lib/, app/, vendor/, pub/, bin/, setup/, generated/), so that cleaning one copy leaves the rest. It prints 8194460 when probed, which attackers use to find their own backdoors later.
    • The loader. An obfuscated JavaScript snippet injected into the cms_block and cms_page tables, not into theme files, where file scanners do not look. Stage one replays a payload cached in the visitor's browser under the localStorage key 136c1e07507f4a97, so it keeps running even when the attacker's domain is taken down. Stage two fetches from the current domain: lanhd6549tdhse.top in March, deepveindrilling.com since 7 October 2026, with manulfie.click, neswnsssn.click and additionalver.com in between.
    • The evasion. The October version sends a browser fingerprint first. Security scanners, headless browsers and anything with navigator.webdriver set get nothing back; real shoppers get the payload. Sansec say they have not yet captured the final payload, so the campaign's goal is unconfirmed; earlier stages pointed at crypto-themed lookalike domains.

    Sansec's 24 October figures: 953 stores hit since July 2025, 83 of them carrying the newest domain, 60 of those 83 already infected by an earlier version. Of 169 Magento 2 installs missing at least one core patch, 102 also had files uploaded through PolyShell or SessionReaper. And a line every merchant should read twice: "Patched stores get the loader too." The patch closes the door. It does not evict anyone already inside.

    How to check whether your store was hit

    Run these on the server as the Magento file owner, from the Magento root. Nothing here changes anything.

    List everything in the upload directory. If your catalogue has no file-type custom options, every file is suspect. If it does, look for script extensions, double extensions and names that match the list above:

    find pub/media/custom_options/ -type f ! -name '.htaccess' -printf '%TY-%Tm-%Td %p\n' | sort

    Look for the backdoor and the other names Sansec have catalogued:

    find . -type f \( -name 'accesson.php' -o -name 'json-shell.php' -o -name 'bypass.phtml' -o -name 'ato_poc.html' \) 2>/dev/null

    Search the CMS tables for the loader. The update_time column tells you when the attacker last wrote to the row:

    SELECT 'block' AS t, block_id AS id, identifier, update_time FROM cms_block
     WHERE content REGEXP 'fpCode|se_referrer|136c1e07507f4a9|deepveindrilling|lanhd6549tdhse|additionalver|neswnsssn|manulfie'
    UNION ALL
    SELECT 'page', page_id, identifier, update_time FROM cms_page
     WHERE content REGEXP 'fpCode|se_referrer|136c1e07507f4a9|deepveindrilling|lanhd6549tdhse|additionalver|neswnsssn|manulfie';

    Then review admin_user for accounts you did not create, integration and oauth_token for API access you do not recognise, the crontab for the web user, and running processes. In the web server logs, the upload attempts are POST or PUT requests to /V1/guest-carts/ ending in /items, and the follow-up checks are GET requests for paths under /media/custom_options/quote/, often with a ?c=id query string, which is the attacker asking the shell to run the id command.

    If any of that turns something up, treat it as a compromise rather than a near miss: the uploaded files are the easy part. The clean-up has to find the backdoors, remove the loader from the database, and rotate the database, admin, API and encryption credentials, because the webshell could read app/etc/env.php. Our Magento malware clean-up page explains how we approach that for stores we host.

    How to fix it and stay fixed

    1. Apply the July 2026 isolated patch for your line, or move to 2.4.9 and then apply its July, August, September and October patches in order. Adobe's prerequisite is the latest patch release of the line: 2.4.9, 2.4.8-p5, 2.4.7-p10, 2.4.6-p15, 2.4.5-p17 or 2.4.4-p18. The APSB26-73 guide walks through it; how to check your store is patched covers the verification.
    2. Verify with Adobe's tool. php vendor/bin/patch-status reports CVE-2026-48356 as PROTECTED, VULNERABLE or UNKNOWN. The tool ships inside the July patch, so if the command is missing, so is the fix. If the tool reports NOT_APPLICABLE, your base version is not one the July patch was built for, which usually means the patch-release upgrade in step 1 has not happened yet.
    3. Make sure nothing under pub/media can execute. On Apache, pub/media/.htaccess should carry php_flag engine 0 and pub/media/custom_options/.htaccess should carry Require all denied. Note that php_flag is ignored when PHP runs under PHP-FPM, which is how most hosts run it now; Require all denied still works. On nginx, the stock nginx.conf.sample only passes index.php, get.php, static.php, the error pages and health_check.php to PHP, and Sansec recommend adding a location block that returns 403 for /media/custom_options/ outright. This stops execution, not the upload, so it is a backstop, not the fix.
    4. Apply SessionReaper's patch too. Sansec's October report found the same operator entering through CVE-2025-54236 (APSB25-88, September 2025) where PolyShell was closed. One without the other leaves the door ajar.
    5. Consider a request filter while you schedule the patch. If your catalogue has no file-type custom options, a web application firewall or ModSecurity rule that rejects guest cart item requests containing file_info blocks the upload before Magento sees it, at no cost to real shoppers. If you do sell products with file options, the patch is the only safe answer.

    What this means for EveryHost customers

    • On our Fully Managed plan we apply Magento security patches for you: staging first, then production in an agreed window, with a rollback plan. If the patch needs a patch-release upgrade first (2.4.7-p5 to 2.4.7-p10, say), we do that step as part of the same job.
    • On Standard and Managed, your developer applies the Magento patch on the staging copy and we coordinate production. The Managed plan's monthly vulnerability check flags a missing July 2026 patch.
    • Sentinel is log-based monitoring that blocks at the server firewall. It is not a web application firewall: it does not inspect the body of a guest cart request, so it does not stop a PolyShell upload. The patch does.
    • If you think a store may already have been hit, open a ticket with the output of the checks above before touching anything. Deleting the uploaded files first destroys the evidence that tells us what else the attacker did.

    See how we handle Magento upgrades and security patching.

    Frequently asked questions

    PolyShell is Sansec's name for CVE-2026-48356, an unrestricted file upload flaw in Magento Open Source and Adobe Commerce. The guest cart REST API accepted a file inside a cart item's custom options without checking the option, the option type or the file extension, and wrote it to pub/media/custom_options/quote/. A polyglot file that is both a valid image and PHP code passes the only check Magento made. Adobe rates it Critical, CVSS 9.6, with no login required.

    Yes. Sansec observed the first attacks on 19 March 2026, a wave that compromised 471 stores in one hour on 30 March, and malicious uploads on 82% of the stores they monitor by 14 April. CISA added CVE-2026-48356 to its Known Exploited Vulnerabilities catalog on 27 October 2026 based on evidence of active exploitation. Adobe's bulletin still says it is not aware of exploits in the wild.

    Magento 2.4.9, released 12 May 2026, and the July 2026 isolated patches from APSB26-73 for 2.4.8-p5, 2.4.7-p10, 2.4.6-p15 and, for Adobe Commerce, 2.4.5-p17 and 2.4.4-p18. A store on an earlier patch release of its line has to upgrade to that patch release first, because the isolated patch only applies there.

    List the files in pub/media/custom_options/ and look for script extensions or names you do not recognise, search the whole install for accesson.php, and search the cms_block and cms_page tables for strings such as fpCode, se_referrer and the loader domains. Check admin_user and integration for accounts you did not create. If you find any of it, rotate every credential and clean the store before patching, because the patch does not remove what is already there.

    Not directly. Binding Operational Directive 26-04 applies to US federal civilian agencies, which must fix CVE-2026-48356 by 10 November 2026. For everyone else the listing is a signal that the flaw is being used against real stores, and insurers, PCI assessors and payment providers treat an unpatched KEV entry as a known, avoidable risk.

    Want the PolyShell patch applied for you?

    Our Fully Managed plan applies Magento security patches on staging first, then to production in an agreed window, with a rollback plan. If your store needs the patch-release upgrade first, that is part of the same job.