CVE
CVE-2026-75650
CWE
CWE-94
Affected Surface
- Magento Open Source 2.4.7, 2.4.8, and 2.4.9, reproduced vulnerable in public reporting
- Magento Open Source 2.4.6-p15 with July and August 2026 security updates applied, observed compromised in the wild
- Adobe Commerce current supported releases now covered by Adobe's emergency `APSB26-146` / `VULN-39341` guidance
- Headless and PWA storefronts that must keep GraphQL exposed to the internet
- Linux hosts running Magento under unprivileged site users, where the post-exploitation implant persists through cron
StyleSmuggler remains the strongest application-security story from the last three days. Public reporting on 5 September showed active, unauthenticated exploitation against Magento Open Source, and Adobe has now confirmed the issue as CVE-2026-75650 with emergency bulletin APSB26-146 and hotfix VULN-39341. The attack matters because it does not look like a normal checkout bug. The public chain abuses a frontend input surface, crosses into Magento’s template and setup internals, and ends with server-side PHP execution plus a persistent Linux implant.
The vendor update closes the biggest uncertainty from the first 48 hours, but it does not make the incident routine. Stores that were exposed before the hotfix still need incident-response work, because the published post-exploitation behavior persists as the site user through cron and survives past the initial web request.
Affected projects and versions
The affected projects currently called out in public reporting are:
- Magento Open Source
2.4.7,2.4.8, and2.4.9, where the full unauthenticated chain was reportedly reproduced on clean installs. - Magento Open Source
2.4.6-p15with July and August 2026 security updates applied, where Sansec says the first known victim still showed a cleansecurity:patch-status. - Adobe Commerce current supported releases, now formally addressed by Adobe’s
APSB26-146response and theVULN-39341hotfix track.
The current evidence also suggests uneven operational impact by storefront model. Disrex’s incident follow-up says headless and progressive web app storefronts usually need GraphQL exposed, while many classic and Hyva storefronts can disable it temporarily with less business impact.
What the public chain currently supports
The clearest public description is Sansec’s two-stage outline:
POST /graphql?styles[...]=
-> attacker poisons a file Magento later reads or renders
-> a payment failure path triggers Magento's built-in failed-payment email
-> Magento renders attacker-controlled PHP during email generation
-> the dropper downloads and launches a Linux implant
Sansec also published these request shapes as indicators tied to observed attacks:
POST /graphql?styles[....]=
POST /paypal/transparent/response/?<?=eval(base64_decode('....
GET /customer/section/load/?sections=customer&force_new_section_timestamp=true
Those indicators are not the same thing as a full proof of concept. The exact chain is still partly opaque. Sansec said a fuller breakdown of the gadget chain and implant would follow later. The important point for defenders is simpler: real stores were compromised through an unauthenticated path before the vendor hotfix landed.
Why the failed-payment email matters in code
The failed-payment email is not a made-up execution sink. Magento really does generate it from checkout exception handling. In app/code/Magento/Checkout/Controller/Onepage/SaveOrder.php, a localized exception path calls sendPaymentFailedEmail():
$this->_objectManager->get(\Magento\Checkout\Helper\Data::class)
->sendPaymentFailedEmail($this->getOnepage()->getQuote(), $e->getMessage());
Inside Magento\Checkout\Helper\Data, that helper builds a transactional email with template variables such as reason, items, billingAddressHtml, shippingAddressHtml, and paymentMethod:
$transport = $this->_transportBuilder->setTemplateIdentifier(
$template
)->setTemplateOptions(
[
'area' => \Magento\Backend\App\Area\FrontNameResolver::AREA_CODE,
'store' => Store::DEFAULT_STORE_ID
]
)->setTemplateVars(
[
'reason' => $message,
'checkoutType' => $checkoutType,
That is why Sansec’s description matters: if an attacker can poison content that later reaches transactional template rendering, the email path becomes an execution boundary worth treating as production code, not as a harmless notification.
The suspected DI compiler sink is plausible, and still unconfirmed
The most technical follow-up came from incident-response reporting tied to Disrex. Their read is that the chain eventually drives Magento code under setup/src/Magento/Setup/Module/Di/Code/, which exists to support dependency-injection compilation, into including attacker-chosen PHP from a poisoned path.
One public source file in that area, ClassesScanner.php, shows why defenders should take that theory seriously:
public function getList($path)
{
$realPath = realpath($path);
...
$recursiveIterator = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($realPath, \FilesystemIterator::FOLLOW_SYMLINKS),
\RecursiveIteratorIterator::SELF_FIRST
);
...
if (!class_exists($className)) {
require_once $fileItemPath;
}
}
If code meant for setup-time scanning becomes reachable in an HTTP execution path with attacker influence over $path or over the files inside it, require_once $fileItemPath; stops being harmless compiler plumbing and becomes a straight server-side code loading primitive.
That said, defenders should separate “plausible” from “confirmed.” Sansec had not confirmed the exact sink at publication time, and Disrex explicitly framed its own work as live incident-response analysis, not as a vendor-validated root cause. Treat public guards in this area as hardening layers, not as a complete fix.
Post-exploitation behavior on Linux hosts
Once the chain lands, the attacker does not stop at one PHP payload. Public reporting describes a small Rust implant that persists as the Magento site user, not as root. The process is disguised as a kernel worker:
process [kworker/u:8:0]
file ~/.local/share/.gvfsd/gvfsd-user
cron */5 * * * * exec <home>/.local/share/.gvfsd/gvfsd-user
That choice matters operationally:
- A real kernel
kworkerthread is owned byroot. A bracketedkworkerowned by a site user is suspicious. - The implant sits outside the document root, so web-root-only scans can miss it.
- Disrex reported a case where the running binary under
/proc/<pid>/exediffered from the file on disk, so hashing only the file path is not enough.
Sansec published two sample hashes:
e315687a1dfe61ef4a5a5642214db6d3b2b05d81391285eebc2af664641a26a7
b79dfdc1eed860e0b76c629d6adfce251db379b0b45a6d728d4ef483f7551420
Follow-up reporting added more indicators, including direct cron-spool writes and extra source IPs. That is useful context, but it does not change the main response rule: hunt for the running process, the persistence path, and the poisoned Magento logs together.
Detection and hunting
Start with the Linux host, then pivot back into Magento logs and application behavior.
Look for the implant and persistence:
ps -eo user,pid,rss,comm,args | rg '\[kworker/u:8:0\]|gvfsd-user'
ls -la ~/.local/share/.gvfsd /tmp/.kw_* /tmp/.gvfsd-* 2>/dev/null
rg -n 'gvfsd-user|/tmp/.kw_' /var/spool/cron /var/spool/cron/crontabs 2>/dev/null
Look for poisoned files and execution markers in Magento-managed paths:
rg -n 'X[_-]?TRACE_|<\?=eval\(base64_decode|array_merge\(' var/report var/log/system.log
If you find a live process, hash both the on-disk file and the running executable:
sha256sum ~/.local/share/.gvfsd/gvfsd-user
sha256sum /proc/<pid>/exe
At the application layer, investigate any sudden burst of “Payment Transaction Failed” notifications, checkout exceptions that do not line up with normal payment-provider failures, and requests hitting /graphql with suspicious styles[...] parameters.
Official mitigation now that Adobe has shipped a fix
There is finally a vendor-backed primary action:
- Apply Adobe’s
VULN-39341hotfix for the exact Magento Open Source or Adobe Commerce branch you run. - Verify the patch state before assuming the store is covered. Adobe’s own cloud guidance uses:
vendor/bin/magento-patches -n status | grep "39341\\|Status"
- Rotate the encryption key and any credentials that may have been readable from
app/etc/env.phpor from the site user’s environment. Adobe’s emergency guidance now makes that credential-rotation step explicit. - If you cannot patch immediately, disable GraphQL if the storefront model allows it.
- If GraphQL must stay on, add temporary request filtering around known
styles[...]abuse patterns and treat those rules as campaign-specific containment, not as a fix. - Harden the host so a PHP dropper has fewer places to land. Public incident-response guidance specifically calls out
proc_openand executable temporary directories.
Example containment steps to evaluate in staging first:
disable_functions = proc_open
tmpfs /tmp tmpfs rw,nosuid,nodev,noexec 0 0
tmpfs /var/tmp tmpfs rw,nosuid,nodev,noexec 0 0
tmpfs /dev/shm tmpfs rw,nosuid,nodev,noexec 0 0
Several unofficial Magento hardening patches also appeared before Adobe published its response. They focus on preventing setup-time DI scanner paths from running under web requests or on blocking specific email-template and report-processing behaviors. They are now fallback hardening measures, not the primary remediation path. Public reporting already notes compatibility risk with some third-party modules, so treat them as temporary guards around the official hotfix, not a replacement for it.
Response priorities if compromise is suspected
If you suspect a store has already been hit:
- Preserve the process and filesystem evidence before cleaning aggressively.
- Remove persistence before killing the process, because the process may recreate the cron entry.
- Invalidate Magento sessions.
- Rotate Magento admin credentials, payment-provider secrets, integration keys, and any other credentials stored in
app/etc/env.phpor reachable from the site user. - Rotate
crypt/keyand other encrypted application secrets in line with Adobe’s hotfix guidance if incident scoping suggests the attacker could read them.
Do not let a clean patch-status report lull you into delaying response. The first public victim already had current Adobe security updates for its release line. StyleSmuggler is a reminder that the exploitable boundary in a large PHP platform is often the space between subsystems: API input, templating, setup code, background email generation, and host-level persistence.
From research to remediation
Check whether this pattern exists in your codebase
Turn this research into a remediation workflow. Use AI-native static analysis to find similar application vulnerabilities and generate review-ready fixes.
References
- Adobe Experience League: urgent action required for CVE-2026-75650
- Sansec: StyleSmuggler disclosure
- Aikido: StyleSmuggler fix for Magento and Adobe Commerce
- NCIJ Network: follow-up reporting with Disrex incident details
- Security Online: StyleSmuggler summary
- Magento source: Checkout helper sendPaymentFailedEmail()
- Magento source: Setup DI ClassesScanner