Arditore
Français

Blog

StyleSmuggler: the crash log was the payload

CVE-2026-75650 turns Magento's own error reporting into a file-write primitive, then executes it while rendering an email. CVSS 10.0, unauthenticated, and exploited before the patch existed.

3 min read

  • vulnerability
  • php
  • magento
  • forensics

Adobe shipped an out-of-band hotfix on 7 September for CVE-2026-75650, a CVSS 10.0 unauthenticated remote code execution flaw in Adobe Commerce, Adobe Commerce B2B and Magento Open Source. CISA added it to the Known Exploited Vulnerabilities catalogue the next day. Every version from 2.4.4 through 2.4.9 is affected, along with B2B 1.3.3 to 1.5.3. Anything on 2.2, 2.3 or 2.4.0 to 2.4.3 is out of support and gets no official patch at all.

Sansec, who reproduced the chain and named it StyleSmuggler, recorded the first confirmed exploitation on 4 September at 22:20 UTC. Unsuccessful probing goes back to 23 August. The patch landed on 7 September at 20:20 UTC. That is a fortnight of probing and three days of confirmed exploitation before a fix existed.

The interesting part is stage one

Most template injection bugs are a single move: you get your input into a template, the engine evaluates it, you win. This one needs two, and the first move is what makes it worth reading about.

The attacker sends PHP source code in the query string of a request to /paypal/transparent/response/. The request fails. Magento does what it is supposed to do when a request fails: it writes a report. That report, at var/report/<sha256>, contains the entire request — including the PHP.

The application’s own crash logging is the file-write primitive. Nothing was misconfigured. Error reporting worked exactly as designed, and designed behaviour put attacker-controlled bytes on disk at a predictable path.

Stage two is a POST to /graphql that assembles a gadget chain out of styles parameters:

styles[first]=../var/report/<sha256>
styles[generatorClass]=Aws\S3\S3Client

That reaches the Laminas ClassMapAutoloader, which treats the report file as a PHP class map and includes it. The code runs while Magento renders its standard Payment Transaction Failed Reminder email. Improper neutralisation of special elements in a template engine — CWE-1336 — but arrived at sideways, through the autoloader, using two pieces of ordinary framework behaviour that are each perfectly reasonable alone.

Patching is not remediation

This is where I would push back on how the advisory reads to a busy operator. Applying VULN-39341 closes the door. It does nothing about anyone who already walked through it.

Magento’s encryption key protects integration tokens, payment gateway credentials and system-privileged automation tokens. An attacker with code execution has that key, and therefore has everything it decrypts. Rotating the key alone is theatre: you have to rotate every credential that was ever encrypted under it — API tokens, gateway credentials, admin passwords, database credentials, SSH keys.

If your store was reachable and unpatched between 4 and 7 September, treat it as compromised until you have evidence otherwise. Not the other way around.

What to look for

Verify the patch actually applied:

vendor/bin/magento-patches -n status | grep "39341\|Status"

Then go looking. Sansec’s published indicators:

  • Background processes wearing plausible names — [kworker/u:8:0], fc-cache, chronyd
  • PHP files anywhere under pub/media/, which should never contain executable code
  • Cron entries invoking binaries out of /tmp or a home directory
  • Exception log entries containing Map file provided does not exist alongside Laminas\Loader\Exception

That last one is the useful one, and it is worth understanding why. It is the failed attempt — the autoloader complaining that the map file it was pointed at is not there. Successful exploitation is quieter. A log full of those errors means someone was working on you; an empty log means nothing either way.

Also check var/report/ itself. The staging mechanism leaves the payload sitting on disk under a content-addressed name, which is unusually convenient: the artefact of stage one survives, timestamped, whether or not stage two succeeded.

The pattern worth taking away

Nobody wrote a vulnerable line here. Error reporting writing requests to disk is correct. An autoloader loading a class map is correct. A template engine rendering a transactional email is correct. The bug is in the seam, and seams are where reachability analysis stops looking.

If you run this stack, patch, then assume the key is gone and act accordingly.


Sources: Sansec’s StyleSmuggler research · Adobe APSB26-146 · Adobe Commerce advisory

All writing