Tutorial

PolyShell CVE-2026-48356: check and fix your Magento stores

Security & Monitoring12 min read17 steps

CVE-2026-48356, nicknamed PolyShell, entered the CISA KEV catalog on October 27, 2026: exploitation of Adobe Commerce and Magento Open Source stores has been observed. For an agency, the question is not only "should we update", but "which stores lack the APSB26-73 fix, and which already carry a webshell". A patch removes the flaw; it removes neither the dropped files nor the injected JavaScript. Here is the inventory, the update, four compromise checks and credential rotation, with a dated status report to hand to each client.

Contents· PolyShell: what is established, where sources differ1/14
  1. 01PolyShell: what is established, where sources differ
  2. 02What the sources say, and what you take from them
  3. 03Why the patch does not close the case
  4. 04What this procedure leaves in your hands
  5. 05Affected and fixed versions according to APSB26-73
  6. 06Inventory the version of every store
  7. 07Freeze the state before touching anything: it is also evidence
  8. 08Apply the fix without a long outage
  9. 09Look for traces of compromise
  10. 10Hardening: PHP has no business under pub/media
  11. 11Troubleshooting: common blockers during the procedure
  12. 12After the cleanup: what must be rotated
  13. 13The dated status report to hand to each client
  14. 14What you keep, and the sources to cite

PolyShell: what is established, where sources differ

CVE-2026-48356, nicknamed PolyShell, affects Adobe Commerce and Magento Open Source. The NVD entry, published on July 14, 2026 from Adobe's submission, classifies it as CWE-434 (unrestricted upload of a file with a dangerous type), with a CVSS 3.1 score of 9.3 and the vector AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N. The fix is Adobe bulletin APSB26-73. On October 27, 2026, CISA added it to its Known Exploited Vulnerabilities (KEV) catalog, with a November 10, 2026 deadline for US federal agencies: exploitation is no longer a hypothesis.

The sources do not describe the flaw the same way. NVD describes arbitrary code execution "in the context of the current user" that requires interaction: a victim has to visit a crafted URL or a compromised page, and the impact reaches beyond the vulnerable component. Sansec and the specialist press describe file uploads that end in webshells on the server. We do not decide between these two readings. The prudent course for an agency is to treat every store still missing the fix as a store that may already carry a webshell.

What the sources say, and what you take from them

Scroll the table

SourceWhat it statesWhat you take from it
NVDCWE-434, CVSS 3.1 score of 9.3, interaction required, execution in the context of the current userThe identifiers to record in the client file
CISA, KEV catalogExploitation observed, added on October 27, 2026, federal deadline of November 10, 2026A working horizon, not a comfortable date
Adobe, bulletin APSB26-73Versions with the 2026-jul suffix are not affectedThe target version for each branch
Sansec, March 30, 2026Mass attack wave: 471 stores compromised in one hour, a PHP webshell followed by `accesson.php` backdoorsThe files to look for on disk
Sansec, October 24, 2026JavaScript loader in `cms_block`, a campaign tracked since July 2025 across 953 stores; 102 of 169 unpatched installations carried uploaded filesThe queries to run on the database
Specialist pressFile uploads leading to webshellsA reading to cross-check, not a primary source

Why the patch does not close the case

Applying APSB26-73 removes the flaw. It removes nothing that has already come in. A webshell dropped before the update stays on disk, an accesson.php backdoor keeps answering, a script injected into cms_block keeps being served to every visitor, and an admin account created by the attacker stays valid. Sansec puts it this way: removing the scripts does not remove the attacker's access.

Sansec's second study shows why the question applies to a whole portfolio. Of 169 unpatched Magento 2 installations examined, 102 carried files uploaded through PolyShell or SessionReaper (CVE-2025-54236, fixed by bulletin APSB25-88), which is 60%. The order of work is therefore fixed: inventory, frozen state, update, search for traces, credential rotation, then a dated status report for the client. Skipping the rotation to save an hour leaves the attacker the keys they may already have copied.

What this procedure leaves in your hands

  • An inventory per store — edition (Commerce or Open Source), exact version, whether the 2026-jul fix is present.
  • A target version per branch — read from bulletin APSB26-73, with no guessing at the numbering.
  • A frozen state before any work — snapshot and database export kept as evidence, before any cleanup.
  • Four repeatable checks — files under pub/media, accesson.php backdoors, JavaScript in cms_block and in cms_page.
  • A complete credential rotation — admin accounts, API and integration keys, database, encryption key, SSH and SFTP.
  • A dated status report for each client — what was checked, found and fixed, and what was not.

Affected and fixed versions according to APSB26-73

Scroll the table

Product and branchAffected up toFixed version
Adobe Commerce 2.4.92.4.92.4.9-2026-jul
Adobe Commerce 2.4.82.4.8-p52.4.8-2026-jul
Adobe Commerce 2.4.72.4.7-p102.4.7-2026-jul
Adobe Commerce 2.4.62.4.6-p152.4.6-2026-jul
Adobe Commerce 2.4.52.4.5-p172.4.5-2026-jul
Adobe Commerce 2.4.42.4.4-p182.4.4-2026-jul
Magento Open Source 2.4.92.4.92.4.9-2026-jul
Magento Open Source 2.4.82.4.8-p52.4.8-2026-jul
Magento Open Source 2.4.72.4.7-p102.4.7-2026-jul
Magento Open Source 2.4.62.4.6-p152.4.6-2026-jul
Adobe Commerce B2B1.5.3, 1.5.2-p5, 1.4.2-p10, 1.3.4-p17, 1.3.3-p181.5.3-2026-jul, 1.5.2-2026-jul, 1.4.2-2026-jul, 1.3.4-2026-jul, 1.3.3-2026-jul
Adobe Commerce Events1.20.0 and earlier1.21.0
Magento Open Source 2.4.5 and 2.4.4Not in the NVD listNo conclusion: read the Adobe advisory

Inventory the version of every store

  1. Read the declared version

    cd /var/www/client-store
    bin/magento --version
    The command prints the edition and the number. The path is an example: adapt it to each hosting setup. Run it as the system user that owns the files, not as root, so you do not change the cache permissions.

  2. Cross-check with Composer

    composer show magento/product-community-edition
    for Magento Open Source, or
    composer show magento/product-enterprise-edition
    for Adobe Commerce. Composer reads what is actually installed. If the two readings differ, Composer is authoritative, and the gap gets recorded.

  3. Sweep an entire server

    find /var/www /home -name composer.lock -not -path '*/vendor/*' -exec grep -H -A1 '"name": "magento/product-' {} +
    Each file listed belongs to a Magento installation, and the version line follows the package name. A public staging site or an old unpacked copy counts as a store: it is exposed in the same way if it is served.

  4. Classify with the version table

    Compare the number you found with the table above. Reading rule: any version without the 2026-jul suffix for its branch needs action. For Magento Open Source 2.4.5 and 2.4.4, which are not in the NVD list, do not write "not affected": refer to the Adobe bulletin and treat the store as exposed until you have read otherwise.

  5. Record one row per store

    Client, server, path, edition, version found, date and time of the check. Add right away the columns you will need later: fix applied, result of the four checks, credentials rotated. This table becomes the central document of the file handed to the client.

Freeze the state before touching anything: it is also evidence

Before any change, freeze the store as you found it. On a VPS, a VPS snapshot, if your host offers one, captures the whole disk; add a database export and a code archive on storage the update does not touch. The difference between the two tools is covered in our snapshot versus backup comparison.

This state serves twice. It lets you roll back if the update breaks checkout. Above all, it preserves evidence: if the attacker got in, the dropped files, their dates and the modified CMS blocks are in this copy, and nowhere else once the cleanup is done. CISA also points to its forensic triage requirements for affected systems. Do not delete or overwrite this state until the case is closed.

A branch upgrade, from 2.4.6 to 2.4.9 for example, is a separate project: its Composer procedure and support calendar are in our upgrade guide. Here, each store stays on its branch and only receives the fix.

Apply the fix without a long outage

  1. Rehearse on a staging copy

    Restore the frozen state to a staging environment, or clone the store, and run the update there first. Time each command: that duration sets the maintenance window you announce to the client.

  2. Pin the fixed version

    composer require magento/product-community-edition=<fixed-version> --no-update
    Replace the package with magento/product-enterprise-edition for Adobe Commerce, and <fixed-version> with the 2026-jul version of your branch, exactly as the bulletin writes it.

  3. Resolve and validate the lock file

    composer update magento/product-community-edition --with-all-dependencies
    Review the list of changed packages. The composer.lock you obtain and test is the one you will deploy: production no longer resolves anything, it installs.

  4. Open the maintenance window in production

    bin/magento maintenance:enable
    bin/magento maintenance:allow-ips <your-ip>
    Everything before this point happened without stopping sales. The second command lets you test the store before it reopens.

  5. Install and apply

    composer install --no-dev
    bin/magento setup:upgrade
    bin/magento setup:di:compile
    bin/magento setup:static-content:deploy
    With a lock file already validated, the outage is limited to these four commands.

  6. Reopen and verify

    bin/magento maintenance:disable
    composer show magento/product-community-edition
    The installed version must be the fixed version of your branch. Place an order with the payment gateway in test mode, then record the version and time in the table.

Look for traces of compromise

  1. List files dropped under pub/media

    find pub/media/custom_options/ pub/media/customer_address/ -type f ! -name '.htaccess'
    A command published by Sansec, to run from the store root. Every file listed needs review, especially a PHP script. Copy it outside the public tree with its modification date before deleting it.

  2. Search for accesson.php backdoors

    find . -name 'accesson.php' -type f
    Sansec reports this file "in multiple directories": run the search from the root, not only under pub/. An empty result proves that this particular file is absent, not that no backdoor exists.

  3. Query the cms_block table

    SELECT block_id, identifier, update_time FROM cms_block WHERE content LIKE '%fpCode%' OR content LIKE '%se_referrer%' OR content LIKE '%localStorage.getItem%';
    A query published by Sansec. Add the installation's table prefix if there is one. The update_time column helps date the injection.

  4. Query the cms_page table

    SELECT page_id, identifier, update_time FROM cms_page WHERE content LIKE '%fpCode%' OR content LIKE '%se_referrer%' OR content LIKE '%localStorage.getItem%';
    The same check on CMS pages. A result is not necessarily malicious: localStorage.getItem can appear in a legitimate script. Read the content before concluding.

  5. Match against published indicators

    For the March 2026 wave, Sansec published a loader domain, lanhd6549tdhse.top, a localStorage key, 136c1e07507f4a97, and a backdoor marker, 8194460. Look for them in the previous results and in the files you found, for example with grep -rl 'lanhd6549tdhse' pub/ app/. This list is not exhaustive: their absence does not clear a store.

  6. Check administrator accounts

    SELECT user_id, username, email, created, logdate, is_active FROM admin_user ORDER BY created DESC;
    An account nobody recognizes, or one created close to the date of a suspicious file, gets disabled and then documented. The monthly check of these points on each client VPS is described in our audit checklist.

Hardening: PHP has no business under pub/media

Independently of PolyShell, a directory that receives files sent by visitors should never execute PHP. Check that your nginx or Apache configuration refuses to execute scripts under pub/media, and test it on staging with a harmless file. This is not a mitigation published by Adobe for this CVE, and it does not replace the fix: it is general hardening that reduces the effect of a future successful upload.

Troubleshooting: common blockers during the procedure

"Your requirements could not be resolved to an installable set of packages." Composer refuses the requested version: a third-party module pins a dependency, or the stability constraint in composer.json excludes the target version. The command composer why-not magento/product-community-edition <fixed-version> names the package that blocks. Sort it out on staging, never in production.

"Please upgrade your database: Run "bin/magento setup:upgrade" from the Magento root directory." The store shows this message after the code update: the setup:upgrade step was not run, or it failed. Run it again, then the compilation.

"Table '…cms_block' doesn't exist" when running the Sansec query: the installation uses a table prefix. Read the prefix in the store configuration and add it to the table name.

"No such file or directory" on the pub/media find command: the custom_options or customer_address directory does not exist on this store. Record it in the table; it is neither a failure nor proof that the store is clean.

A store that stays in maintenance: check that no maintenance flag remains and run bin/magento maintenance:disable again as the user that owns the files.

After the cleanup: what must be rotated

  • Administrator passwords — every account in admin_user, including the ones you consider sound.
  • API keys and integrations — tokens of the integrations declared in the admin, keys for third-party services (payment, shipping, ERP) stored in the configuration.
  • Database credentials — a new password, updated in the store configuration.
  • Encryption key — to be changed following the Adobe documentation, after assessing the effect on data that is already encrypted.
  • SSH and SFTP access — passwords, authorized SSH keys, unknown system accounts.
  • Hosting access — control panel and backups, which also give access to the files.

The dated status report to hand to each client

Scroll the table

ColumnWhat you writeWhy
Version before and afterNumbers read by Composer, with date and timeShows that the APSB26-73 fix is in place
Frozen stateReference of the snapshot and of the database exportAllows rollback and forensic review
Files under pub/mediaPaths and dates of the files found, or "none"Check published by Sansec
accesson.phpPaths found, or "none"Backdoor reported by Sansec
cms_block and cms_pageIdentifiers listed and verdict after readingInjected JavaScript served to visitors
Admin accountsUnknown accounts disabled, or "none"Access left by the attacker
Credentials rotatedSecrets changed and date of the changeCloses what the attacker may have copied
Not checkedWhat you could not look at, and whyAn honest status beats an "all is well"

What you keep, and the sources to cite

When a store is found compromised, the agency is the one the client calls. Keep that role: you hold the relationship, the diagnosis and the dated report; the platform holds the infrastructure, the root access to the VPS that lets you run these checks, and the snapshot before any work. We do not change a store's code on your behalf: updating Magento remains the agency's task. Keep the table template as well: the next flaw affecting a store will follow the same sequence, with one more row in the inventory.

Primary sources:
NVD entry for CVE-2026-48356
Adobe bulletin APSB26-73
CISA alert of October 27, 2026
Sansec, PolyShell mass attack wave
Sansec, JavaScript loader in cms_block

A portfolio of stores, a single inventory

For a portfolio of client stores, the real cost is the lack of an inventory. On the agencies page, see how to centralize the portfolio, the infrastructure and its status in one place: you keep the client relationship, we hold the infrastructure.

Related articles

Magento 2.4.6 out of support: upgrade to 2.4.9, short cutover
Security & Monitoring9 min read

Magento 2.4.6 out of support: upgrade to 2.4.9, short cutover

Standard support for Magento 2.4.6 has ended. Adobe's dates, the server stack 2.4.9 needs, and a Composer upgrade rehearsed in staging, with downtime cut to the switch.

Read the article →
How to install Magento on a VPS
Self-hosting3 min read

How to install Magento on a VPS

Install Magento on a ServOrbit VPS: complex catalogue, Docker stack, HTTPS and a link to the official Adobe Commerce documentation.

Read the article →
VPS snapshot vs backup: what differs and how restore works
Security & Monitoring9 min read

VPS snapshot vs backup: what differs and how restore works

VPS snapshot or backup: what each one protects, what it does not, how restoring works, and a decision rule for the VPS you run for your clients.

Read the article →
Monthly client VPS security audit: a 45-minute checklist
Security & Monitoring10 min read

Monthly client VPS security audit: a 45-minute checklist

Seven checks to run every month on a client VPS: updates, kernel, SSH accounts, ports, certificates, backups, logs. Includes a dated one-page report.

Read the article →
Bricksforge CVE-2026-85097: update and audit your WordPress fleet
Security & Monitoring10 min read

Bricksforge CVE-2026-85097: update and audit your WordPress fleet

Bricksforge 3.1.8.10 fixes CVE-2026-85097, an exploited unauthenticated upload. wp-cli inventory, dropped PHP files, access logs, secrets to rotate.

Read the article →
Drupal Commerce CVE-2026-118539: patch and audit orders
Security & Monitoring10 min read

Drupal Commerce CVE-2026-118539: patch and audit orders

Commerce Core flaw under exploitation, advisory SA-CONTRIB-2026-254: find affected versions, move to 3.3.13 or 8.x-2.41, then audit your orders.

Read the article →

Need help?

Browse our help center and FAQ, or reach our team — callback, WhatsApp or email. Support in French, English and Arabic.

Message us on WhatsAppopens in a new tab