The Online Store Hack That Survives the Patch

Magento PolyShell (CVE-2026-48356) is now on CISA's exploited list, and its hidden script outlives patches. How to check your clients' stores.

One Magento shop had every core patch installed and had just passed a malware scan, and an hour later it was serving a stranger's script to its shoppers again. Sansec reported that case on October 24, 2026, and on October 27 the US cyber-defence agency CISA added PolyShell (CVE-2026-48356), the Adobe Commerce and Magento upload flaw this campaign used to break in, to its list of actively exploited bugs. The twist: the intruder was already inside, and the script lives in the store's database, which installing a patch doesn't clean.

TL;DR

  • CISA added PolyShell (CVE-2026-48356), a file-upload flaw in Adobe Commerce and Magento, to its catalog of actively exploited bugs on October 27, 2026, per CISA.
  • Exposed: any Adobe Commerce or Magento Open Source store without Adobe's July 2026 security patch, bulletin APSB26-73, per Adobe; infected stores carry a hidden script in the cms_block database table, per Sansec.
  • Preserve evidence, search every store's database and upload folders, remove what you find, change database, admin and API passwords, then install APSB26-73 and the SessionReaper fix APSB25-88, per Sansec.
  • By Sansec's count, the group behind the script has hit 953 stores since July 2025; its final payload hasn't been recovered, so its goal is unknown, per Sansec.

Which Magento and Adobe Commerce versions are affected by CVE-2026-48356?

Every Adobe Commerce and Magento Open Source release up to and including 2.4.9 is affected unless the July 14, 2026 isolated patch from Adobe's bulletin APSB26-73 is installed. Adobe tests that patch only on the latest security release of each line, so a store on 2.4.7-p1 must move to 2.4.7-p10 first. Adobe Commerce Cloud stores get the fix through the latest cloud-patches update instead.

Product Branch Fixed in Source
Adobe Commerce, Magento Open Source 2.4.9 2.4.9-2026-jul Adobe
Adobe Commerce, Magento Open Source 2.4.8 (2.4.8-p5 and earlier) 2.4.8-2026-jul Adobe
Adobe Commerce, Magento Open Source 2.4.7 (2.4.7-p10 and earlier) 2.4.7-2026-jul Adobe
Adobe Commerce, Magento Open Source 2.4.6 (2.4.6-p15 and earlier) 2.4.6-2026-jul Adobe
Adobe Commerce 2.4.5 (2.4.5-p17 and earlier) 2.4.5-2026-jul Adobe
Adobe Commerce 2.4.4 (2.4.4-p18 and earlier) 2.4.4-2026-jul Adobe
Adobe Commerce B2B 1.3.3 to 1.5.3 matching 2026-jul patch CVE record
Adobe Commerce Events 1.20.0 and earlier 1.21.0 Adobe

Magento PolyShell is the name Sansec, an e-commerce security firm, gave the bug when it first reported it on March 17, 2026: a hole in Magento's REST API, the interface apps use to talk to the store, that lets attackers with no login upload code disguised as an image. NVD, the US vulnerability database, rates it 9.3 out of 10; Adobe's bulletin scores it 9.6 and says no authentication is required. Both scores also list user interaction, but treat any unpatched store as reachable. CISA added it on October 27, 2026 and set a due date of November 10, 2026 for federal agencies. Sansec's October 24 report says one group used it, among other ways in, to plant a loader, a small script that fetches more code, on 953 stores since July 2025.

How do I check if a Magento store is hacked?

Check the database first: Sansec found the loader in the cms_block table on 148 server installs and never in the configuration table or theme files. Run these steps from a root shell on each client's web server; the searches cover every store under /var/www, /home and /srv, so add the hosting panel's web root if it differs. If sudo mysql asks for a password, add -u root -p. The campaign began in July 2025 and server logs rarely reach back that far, so search the client's SIEM (central log store) or log archive for older months; a clean on-server result does not rule out an earlier break-in.

  1. Preserve evidence. This copies web logs, every database and the upload folders before anything changes, then records hashes.

    D=/root/ir-polyshell-$(date +%F); sudo mkdir -p "$D"
    sudo cp -a /var/log/apache2 /var/log/nginx /var/log/httpd "$D"/ 2>/dev/null
    sudo mysqldump --all-databases --single-transaction | sudo tee "$D/all-databases.sql" >/dev/null
    sudo find /var/www /home /srv -type d -path '*/pub/media/custom_options' -exec cp -a --parents {} "$D"/ \;
    sudo find "$D" -type f -exec sha256sum {} + | sudo tee "$D.sha256"
    
  2. Read each store's version. This reads the installed Magento release from Composer's lock file without running store code. Pass: the latest security release of its line, plus the Commerce Version Tool that ships with the July patch reporting CVE-2026-48356 as protected, per Adobe.

    sudo find /var/www /home /srv -name composer.lock -not -path '*/vendor/*' -exec grep -H -A1 '"name": "magento/product-' {} \;
    
  3. Search every store database for the loader. This uses Sansec's patterns plus the newest domain, deepveindrilling.com; update_time shows the attacker's latest write. Review each hit, since legitimate blocks can use localStorage too.

    for t in $(sudo mysql -N -e "SELECT CONCAT(table_schema,'.',table_name) FROM information_schema.tables WHERE table_name LIKE '%cms\_block' OR table_name LIKE '%cms\_page'"); do
      echo "== $t"
      sudo mysql -N -e "SELECT identifier, update_time FROM $t WHERE content LIKE '%fpCode%' OR content LIKE '%se_referrer%' OR content LIKE '%localStorage.getItem%' OR content LIKE '%deepveindrilling%'"
    done
    
  4. Find uploaded files and backdoors. Any file in these upload folders other than .htaccess is suspect, including fake PNG images, and accesson.php is a known backdoor name.

    sudo find /var/www /home /srv -type f \( -path '*/pub/media/custom_options/*' -o -path '*/pub/media/customer_address/*' \) ! -name .htaccess
    sudo find /var/www /home /srv -type f -name accesson.php
    
  5. Search web logs for requests to scripts in the upload folder. A hit means someone ran code they uploaded.

    sudo zgrep -hE 'media/custom_options/.*\.(php|phtml|phar)' /var/log/nginx/access.log* /var/log/apache2/access.log* /var/log/httpd/access_log* 2>/dev/null
    
  6. List admin accounts in every store. Sansec found a rogue admin on the patched store; flag any name the client doesn't recognise.

    for t in $(sudo mysql -N -e "SELECT CONCAT(table_schema,'.',table_name) FROM information_schema.tables WHERE table_name LIKE '%admin\_user'"); do
      echo "== $t"; sudo mysql -e "SELECT username, email, created, logdate, is_active FROM $t ORDER BY created DESC"
    done
    
  7. Check running processes and scheduled jobs. This shows children of the web and PHP workers (still-running processes only) and every user's cron jobs; anything besides Magento's own bin/magento cron:run needs an explanation.

    ps -eo pid,ppid,user,comm,args --forest | grep -E -A3 'php-fpm|apache2|httpd|nginx'
    sudo ls -la /etc/cron* /var/spool/cron/*
    

Indicators from Sansec's loader report and Sansec's PolyShell advisory.

How do I fix CVE-2026-48356 and remove the loader?

Clean first, then patch, because the patch closes the upload hole but leaves the script and any backdoor in place.

  1. Preserve evidence. Confirm step 1's hash file exists before changing anything: sudo ls -la /root/ir-polyshell-*.sha256.

  2. Contain the upload folder. On nginx, add Sansec's rule before any \.php$ location block, then run sudo nginx -t && sudo systemctl reload nginx. Blocking web access does not stop uploads; only the patch or a web application firewall (WAF) that blocks the API call does, per Sansec.

    location ~* ^/pub/media/custom_options/ {
        deny all;
        return 403;
    }
    

    On Apache, confirm each upload folder's .htaccess disables PHP and denies access; pass: every line ends in :2.

    sudo find /var/www /home /srv -path '*/pub/media/custom_options/.htaccess' -exec grep -H -c -E 'php_flag engine 0|Deny from all' {} \;
    
  3. Remove the foothold. Delete the injected script from each block or page step 3 listed, delete the files step 4 found, and disable admin accounts from step 6 that nobody recognises. Pass: rerun steps 3, 4 and 6 and get no unexplained results.

  4. Change passwords. Change the database password (and update it in the store's app/etc/env.php), every admin password and every API integration key. Pass: logging in with the old database password fails.

  5. Patch. Move to the latest security release of the store's line, apply APSB26-73, and install APSB25-88 for SessionReaper (CVE-2025-54236), per Sansec. Pass: step 2 shows CVE-2026-48356 as protected.

Why doesn't patching remove the PolyShell loader?

Adobe's patch changes Magento's code, while the loader is stored as content in the Magento cms_block table, and any access the attacker already holds, such as a rogue admin account, outlives the patch. That is how the 2.4.7-p10 store got deepveindrilling.com at 16:46 UTC on October 23, an hour after a clean scan, per Sansec: a rogue admin account had been sitting there since September 16, and a GSocket backdoor, a remote-access tool, since September 24.

Three more findings from the same report:

  • It hides from scanners. Since October 23, the loader checks whether the visitor is an automated browser and returns nothing to it; when urlscan.io loaded an infected store, it found no added content.
  • Old victims get re-used. Of the 83 stores carrying deepveindrilling.com, 60 already ran an earlier loader from the same operator; the report doesn't say how the other 23 were breached.
  • Missing patches go with uploads. Of 169 infected installs missing at least one core patch, 102 (60%) also had files uploaded through PolyShell or SessionReaper.

The same operator put its loader on 471 stores in one hour on March 30, 2026, per Sansec.

Where KinoSec fits

KinoSec doesn't read store databases, so it won't find a script sitting in cms_block; steps 3 and 6 above do that. What it tests is the way in. PolyShell needed no login on stores open to the internet, and a missed patch left that door open for months. KinoSec runs autonomous web app pentests against your clients' stores: reconnaissance, finding vulnerabilities, chaining exploits and writing up findings with remediation, continuously and on demand. It tests what an attacker could reach from the outside, so a store that slips behind on patches shows up in the report you hand your client, not in Sansec's next count.

Frequently Asked Questions

What does the PolyShell loader do to shoppers?

Nobody knows yet. Sansec has not recovered the final payload, so the campaign's goal is unknown. In December 2025, Sansec saw an earlier stage send a logged-in customer a script from leqdger.click, a domain imitating the crypto wallet brand Ledger.

How do I check if my clients' Magento stores were hit?

  1. Run the database search in step 3 of "How do I check if a Magento store is hacked?".
  2. Run sudo find /var/www /home /srv -type f -name accesson.php.
  3. Run the upload-folder search in step 4 of the same list.

Does blocking the upload folder in nginx stop PolyShell?

No. Sansec says blocking web access to the upload folder does not stop the uploads themselves; only Adobe's APSB26-73 patch or a WAF that blocks the API call does.

Is my Magento store hacked if an online scanner says it's clean?

It can be. Since October 23, the loader checks whether the visitor is an automated browser, and urlscan.io found no added content on an infected store. Search the cms_block table directly.