On September 5, 2026, Sansec disclosed StyleSmuggler, a Magento Open Source and Adobe Commerce zero-day vulnerability that allows unauthenticated remote code execution.
Attacks started on September 4 and exploitation is active. Sansec reproduced the complete attack chain on Magento 2.4.7, 2.4.8 and 2.4.9. Their first confirmed victim was running Magento 2.4.6-p15 with the recent July and August security patches already installed. Check more detailed information at Sansec site.
The attack works in two stages. Malicious PHP is first injected into Magento-controlled data such as report or log files. Magento is then made to process that data through its template system and execute the injected code.
At the time of writing, there is no official Adobe patch for StyleSmuggler. Adobe's next scheduled security release is September 8, but it is not yet confirmed whether it will include a fix.
If you manage a Magento server, there are three separate jobs:
- Check whether the server is already compromised.
- Prevent another StyleSmuggler request from reaching the vulnerable code.
- If compromised, preserve evidence, remove the malware and audit everything the Magento system user could access.
Blocking GraphQL does not clean an already compromised server.
1. Check whether the Magento server is already compromised
Start with read-only checks. Do not immediately reboot the machine, delete files or redeploy Magento.
Check for fake kernel worker processes
One of the clearest indicators observed in affected systems is a process disguised as:
[kworker/u:8:0]
Run:
ps -eo pid,user,rss,args --no-headers | awk '$4 ~ /^\[/ && $2 != "root"'
A real Linux kernel worker runs as root. A process with a kernel-looking name such as [kworker/u:8:0] running as your Magento system user is highly suspicious.
A broader check is:
ps -eo pid,user,comm,args | grep -i kworker
Do not treat every kworker process as malware. Normal Linux servers have many legitimate kernel workers. What matters is the owner, PID, memory usage and executable behind the process.
Sansec specifically lists [kworker/u:8:0] running as part of the StyleSmuggler infection chain.
Check cron persistence
The malware observed in this campaign creates persistence using cron.
Check your current user's crontab:
crontab -l
Then search specifically for known patterns:
crontab -l 2>/dev/null | grep -Ei 'gvfsd|\.kw_'
A known malicious entry looks similar to:
*/5 * * * * exec /home/USER/.local/share/.gvfsd/gvfsd-user
Sansec observed gvfsd-user being restarted every five minutes.
Check known dropped-file locations
Run:
ls -la ~/.local/share/.gvfsd/ /tmp/.kw_* /tmp/.gvfsd-* 2>/dev/null
Known locations include:
~/.local/share/.gvfsd/gvfsd-user
~/.local/share/.gvfsd/.gvfsd_<random>.lock
/tmp/.kw_<random>
An important detail here is that the malware is installed outside the Magento document root.
A malware scan limited to /pub, /public_html or the Magento project directory can therefore report the store as clean while the implant continues to run from the user's home directory.
Check Magento report and log files
Observed variants used Magento's own files during the first stage of exploitation.
Check both var/report and var/log:
grep -rl 'X_TRACE_\|<?php' var/report/ var/log/ 2>/dev/null
Do not check only var/report. Different observed variants have written payloads into different locations.
Check web server access logs
Adjust the path to the access log for your server:
grep -acE 'styles(\[|%5B)|generatorClass|with_resolved|cdnflare' /path/to/access.log
You can also inspect matching requests:
grep -aE 'styles(\[|%5B)|generatorClass|with_resolved|cdnflare' /path/to/access.log
Sansec lists malicious requests to /graphql with styles[...] parameters among the observed indicators.
Unexpected bursts of Magento's Payment Transaction Failed Reminder emails are another useful signal. The victim does not have to open the email—the malicious code executes while Magento renders it.
2. If you find a suspicious process, inspect it before killing it
Do not immediately run kill -9.
First record what the process is doing.
Assume the suspicious PID is 7908:
PID=7908
Inspect it:
ps -fp "$PID"
Check the executable:
ls -l /proc/$PID/exe
readlink -f /proc/$PID/exe
Check its current working directory:
ls -l /proc/$PID/cwd
Check files opened by the process:
lsof -nP -p "$PID"
Check its network connections:
ss -tpn | grep "pid=$PID,"
or:
lsof -nP -i -a -p "$PID"
Don't look only for external connections
This became particularly important during our own investigation.
On one affected server the suspicious kworker process did not expose an obvious external command-and-control connection. Instead, the process had several established connections to the Magento server's own Redis instance.
We identified the Redis endpoint with:
lsof -nP -iTCP:21113
The same Redis process was listening on that port while the suspicious kworker process was connected to it.
You can also identify what is listening on a suspicious port with:
ss -ltnp | grep ':21113'
Replace 21113 with the port found in your connection output.
This matters because an infected server may show no suspicious outbound connection at all. The malware may communicate through services already available to the Magento account, including Redis.
3. Preserve evidence before cleaning the server
If the previous checks indicate compromise, save the state before changing it.
Create a private incident directory:
Q=~/incident-$(date +%Y%m%d-%H%M)
mkdir -p "$Q"
chmod 700 "$Q"
Save the running process list:
ps -eo pid,ppid,user,lstart,rss,args > "$Q/processes.txt"
Save the suspicious process information:
ls -l /proc/$PID/exe /proc/$PID/cwd > "$Q/proc-links.txt" 2>&1
ls -l /proc/$PID/fd/ > "$Q/proc-fds.txt" 2>&1
cat /proc/$PID/status > "$Q/proc-status.txt" 2>&1
If the executable has already been deleted from disk, /proc/$PID/exe may still contain the running binary.
Copy it before killing the process:
cp /proc/$PID/exe "$Q/implant.bin" 2>/dev/null
Hash it:
sha256sum "$Q/implant.bin"
Save cron:
crontab -l > "$Q/crontab.txt" 2>&1
Save network connections:
(ss -tanp 2>/dev/null || netstat -tanp 2>/dev/null) > "$Q/connections.txt"
Save relevant Magento and web server logs before modifying them:
cp -a var/log "$Q/magento-log"
cp -a var/report "$Q/magento-report"
cp -p /path/to/access.log "$Q/access.log"
Do this before running Composer or redeploying Magento. A deployment can replace modified files and timestamps that would otherwise help establish what happened.
Also avoid rebooting at this stage. /proc/<pid>/exe can be the only remaining copy of a malware binary that deleted its original file after starting.
4. Block new StyleSmuggler attacks
Once evidence is preserved, block the attack path while continuing the investigation.
Before disabling GraphQL, verify whether the store actually uses it.
Headless and PWA storefronts depend on it. Some Magento themes and third-party integrations may also use GraphQL.
Check recent traffic:
grep -c '"POST /graphql' /path/to/access.log
A zero does not absolutely prove GraphQL is unused, but it is a useful first check.
Option 1: Cloudflare
If the store uses Cloudflare, an edge rule is usually the quickest option.
Create a WAF/custom rule matching:
http.request.uri.path eq "/graphql"
and set the action to:
Block
If your setup also accepts a trailing slash, block both:
/graphql
/graphql/
Blocking at Cloudflare has the advantage that malicious GraphQL requests never reach the Magento server.
Option 2: Nginx
For a Magento installation that does not need GraphQL:
location ^~ /graphql {
return 403;
}
Validate the configuration before reloading:
nginx -t
Verify:
curl -I https://YOURSTORE/graphql
You should receive 403.
Option 3: Apache
For Apache with rewrite rules:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/graphql/?$ [NC]
RewriteRule ^ - [F,L]
Verify afterwards:
curl -I https://YOURSTORE/graphql
Again, the expected result is 403.
Option 4: Magento CLI — least recommended
You may also see advice to disable GraphQL using Magento's module system.
First inspect GraphQL modules:
bin/magento module:status | grep -i GraphQl
The obvious command would be:
bin/magento module:disable Magento_GraphQl
We consider this the least recommended approach.
Magento_GraphQl is a base Magento module and many GraphQL modules depend on it. Depending on the Magento version and installed extensions, Magento may refuse to disable it because of dependencies.
Do not solve that by blindly running:
bin/magento module:disable Magento_GraphQl --force
on a production store.
For emergency containment, blocking /graphql at Cloudflare, Nginx or Apache is simpler, easier to reverse and does not modify Magento's module dependency graph.
5. Apply the community StyleSmuggler mitigation
Blocking /graphql is useful emergency containment, but there is also a community source patch maintained by DISREXM
This is not an Adobe patch.
The mitigation changes three Magento DI code scanners so they can only execute from PHP CLI. Normal setup:di:compile execution happens through CLI, while web execution through the vulnerable path is blocked.
The patch has been tested by its authors against Magento 2.4.6 through 2.4.9. However, it was produced quickly during an active incident and has not undergone the same review process as an Adobe security patch.
Test it before production deployment.
For an already running server:
cd /path/to/magento
patch -p1 --forward \
< patches/magento/magento2-base/stylesmuggler-di-scanner-guard.patch
Then compile:
bin/magento setup:di:compile
Verify the patch:
grep -c 'StyleSmuggler mitigation' \
setup/src/Magento/Setup/Module/Di/Code/Scanner/ArrayScanner.php
Then check storefront, checkout and Admin normally.
For Composer-based deployments, add the patch through composer-patches so that a future composer install does not silently replace the modified Magento source.
Remove or review the community workaround once Adobe releases an official fix.
6. Clean an infected server
Mitigation stops another attack. It does not remove the existing implant.
The cleanup order matters.
6.1 Remove cron persistence first
Edit the user's crontab:
crontab -e
Remove suspicious entries referring to:
gvfsd
.kw_
Verify:
crontab -l | grep -Ei 'gvfsd|\.kw_'
The command should return nothing.
Do this before killing the malware process. Otherwise cron can simply start another copy.
6.2 Kill the malicious process
Once persistence has been removed:
kill "$PID"
Check:
ps -p "$PID"
If the process refuses to exit:
kill -9 "$PID"
Then repeat the non-root kernel-process check:
ps -eo pid,user,rss,args --no-headers | awk '$4 ~ /^\[/ && $2 != "root"'
It should return nothing suspicious.
6.3 Remove known malware files
After preserving copies:
rm -rf ~/.local/share/.gvfsd/
rm -f /tmp/.kw_* /tmp/.gvfsd-* 2>/dev/null
Check again:
ls -la ~/.local/share/.gvfsd/ /tmp/.kw_* /tmp/.gvfsd-* 2>/dev/null
6.4 Remove poisoned Magento files
Find suspicious files again:
grep -rl 'X_TRACE_\|<?php' var/report/ var/log/ 2>/dev/null
Do not simply delete everything before preserving evidence.
Once copies have been saved, remove affected report files and clean injected log content as appropriate for the installation.
7. Check for other persistence and backdoors
Removing gvfsd-user does not prove the server is clean.
The attacker had code execution as the Magento system user and could write anywhere that user had permission.
Check other cron mechanisms
crontab -l 2>/dev/null
sudo crontab -l 2>/dev/null
Check system cron:
ls -la /etc/cron.d/ /etc/cron.daily/ /etc/cron.hourly/ \
/etc/cron.weekly/ /etc/cron.monthly/ 2>/dev/null
cat /etc/crontab 2>/dev/null
Check timers:
systemctl list-timers --all 2>/dev/null
systemctl --user list-timers --all 2>/dev/null
Check user systemd units:
ls -la ~/.config/systemd/user/ 2>/dev/null
Check SSH access
Inspect:
cat ~/.ssh/authorized_keys
Every key should be accounted for.
Also check timestamps:
ls -la ~/.ssh/
Check shell startup files
Search for obvious downloaders and persistence:
grep -nE 'curl|wget|base64|/tmp/\.|gvfsd|kworker' \
~/.bashrc ~/.bash_profile ~/.profile ~/.zshrc ~/.bash_login 2>/dev/null
Check PHP persistence
Look for PHP configuration that automatically executes another file:
grep -rn 'auto_prepend_file\|auto_append_file' \
.user.ini .htaccess /etc/php*/ 2>/dev/null
Look for PHP files uploaded into media:
find pub/media -type f -name '*.ph*' 2>/dev/null
And recently modified PHP files:
find app vendor pub \
-type f -name '*.php' -newermt '30 days ago' 2>/dev/null
8. Compare the Magento filesystem with known-good code
If the project is stored in Git:
git status --short
Then:
git diff --stat
Find untracked PHP/PHTML files:
git ls-files --others --exclude-standard \
| grep -E '\.(php|phtml)$'
Anything unexpected in:
app/code
vendor
pub
setup
needs investigation.
Do not assume that reinstalling vendor/ alone solves the problem. The malware process runs as the Unix site user and is not limited to Magento PHP code.
9. Check Magento database content
The attacker could access the same database credentials available to Magento.
Check Admin users:
SELECT
user_id,
username,
email,
created,
logdate,
is_active
FROM admin_user
ORDER BY created DESC;
Look for unknown or recently created accounts.
Check integrations:
SELECT
integration_id,
name,
created_at,
status
FROM integration;
Check recent OAuth tokens:
SELECT *
FROM oauth_token
ORDER BY created_at DESC
LIMIT 20;
Check configuration for obvious JavaScript injection:
SELECT
config_id,
scope,
scope_id,
path,
LEFT(value, 300)
FROM core_config_data
WHERE value LIKE '%<script%'
OR value LIKE '%eval(%'
OR value LIKE '%atob(%'
OR value LIKE '%fromCharCode%';
Check recently modified CMS blocks:
SELECT identifier, update_time
FROM cms_block
WHERE update_time > NOW() - INTERVAL 30 DAY
ORDER BY update_time DESC;
And CMS pages:
SELECT identifier, update_time
FROM cms_page
WHERE update_time > NOW() - INTERVAL 30 DAY
ORDER BY update_time DESC;
These queries are not StyleSmuggler signatures. They are simply useful places to look for persistence or injected storefront JavaScript after a server compromise.
10. Check Redis and invalidate sessions
Redis deserves special attention in this incident.
First check Magento's Redis configuration:
grep -nA40 "'cache'" app/etc/env.php
grep -nA30 "'session'" app/etc/env.php
Identify:
- Redis host
- port or socket
- cache database
- page-cache database
- session database
Then inspect connections:
lsof -nP -iTCP:<REDIS_PORT>
or:
ss -tnp | grep ':<REDIS_PORT>'
If you found a suspicious PID earlier:
ss -tpn | grep "pid=$PID,"
If Redis is used for customer/admin sessions, invalidate the session database after containment.
For example:
redis-cli -h <HOST> -p <PORT> -n <SESSION_DB> FLUSHDB
Use FLUSHDB against the specific Magento database rather than blindly running:
redis-cli FLUSHALL
especially on shared hosting or a Redis instance used by multiple applications.
Flushing the Magento session database logs out customers and administrators. After a server compromise, that is desirable because existing authenticated sessions must be treated as potentially exposed.
11. Rotate credentials
Once the malware and persistence have been removed, assume secrets readable by the Magento Unix user may have been exposed.
At minimum review and rotate:
- Magento Admin passwords
- database credentials
- Magento integration/API tokens
- OAuth tokens
- SSH keys accessible to the site user
- deployment keys
- payment-provider credentials
- SMTP credentials
- ERP, CRM and fulfillment API credentials
- CDN and third-party service credentials
- secrets stored in deployment configuration
Inspect app/etc/env.php carefully.
Do not simply replace Magento's crypt/key value manually on a production store. Magento uses this key to encrypt stored configuration values. If the key is considered exposed, encrypted secrets need a controlled rotation/re-encryption procedure.
Also invalidate active Admin sessions after changing Admin credentials.
Credentials should be rotated after containment. Changing passwords while the attacker still has active execution on the server can simply expose the new credentials as well.
12. Verify that the server stays clean
Repeat the original checks.
Processes
ps -eo pid,user,rss,args --no-headers | awk '$4 ~ /^\[/ && $2 != "root"'
Cron
crontab -l | grep -Ei 'gvfsd|\.kw_'
Malware files
ls -la ~/.local/share/.gvfsd/ /tmp/.kw_* /tmp/.gvfsd-* 2>/dev/null
Magento reports and logs
grep -rl 'X_TRACE_\|<?php' var/report/ var/log/ 2>/dev/null
Network connections
lsof -nP -i -a -u "$USER" 2>/dev/null
Look specifically for unexpected long-running processes communicating with Redis or external hosts.
GraphQL
If GraphQL was disabled:
curl -sk -o /dev/null -w '%{http_code}\n' \
'https://YOURSTORE/graphql'
Expected:
403
Storefront
curl -sk -o /dev/null -w '%{http_code}\n' \
'https://YOURSTORE/'
Expected:
200
If the suspicious process or cron entry reappears, another persistence mechanism still exists.
What Magento store owners should do now
If you run Magento 2:
- Check the server for compromise now — processes, cron, Magento logs and access logs.
- Block /graphql if your store does not use it, or apply the community mitigation.
- If indicators are found, preserve evidence before deleting anything.
- Remove malware, cron persistence and any additional backdoors.
- Audit Magento files, database, Redis, SSH access and credentials.
- Rotate exposed credentials and invalidate active sessions.
- Run the checks again after cleanup.
- Install the official Adobe fix as soon as it becomes available.
The main point is simple: blocking GraphQL prevents another StyleSmuggler request, but it does not clean an already compromised Magento server.
Treat a confirmed infection as compromise of the Magento Unix account, not just as a malicious PHP file inside the Magento installation.