On Tuesday, CISA added CVE-2026-111497 (CVSS 9.2) — an unchecked return value vulnerability — along with a second Adobe Commerce/Magento flaw and a vulnerability in Google's Brotli decoder library to its Known Exploited Vulnerabilities (KEV) catalog, citing confirmed evidence of active exploitation. The exploitation campaign, tracked as PolyShell, has already breached hundreds of online stores running Adobe Commerce and Magento Open Source, with attackers deploying web shells and generating suspicious traffic linked to the vulnerable Brotli decoder component.
This is not a theoretical risk. KEV inclusion means exploitation is happening in the wild, at scale, right now. If you operate an Adobe Commerce or Magento storefront — or provide hosting, payment processing, or fulfillment for merchants that do — you are in the blast radius. Web shell access on an e-commerce platform means access to customer PII, stored payment data flows, admin credentials, and a launchpad for Magecart-style skimming. Every hour of dwell time compounds the exposure.
This post breaks down what we know, how the attack chain works from a defender's perspective, and gives you concrete detection rules, hunt queries, and remediation steps you can execute today.
Technical Analysis
Affected Products
- Adobe Commerce (formerly Magento Commerce) — all supported deployment models (on-premises and cloud infrastructure)
- Magento Open Source
- Google Brotli decoder library — bundled transitively in numerous applications, CDNs, and web server modules; the vulnerable decoder is relevant here because attacker tooling and malformed compressed traffic have been observed interacting with the compromised stores
Because Brotli is an embedded library rather than a standalone product, its exposure surface is enormous: any application statically linking the vulnerable decoder inherits the risk. Defenders should inventory not just their storefronts, but anything in their stack that decompresses Brotli content — web servers (nginx brotli module, Apache mod_brotli), CDNs, API gateways, and custom services.
The Vulnerability: CVE-2026-111497 (CVSS 9.2)
CVE-2026-111497 is an unchecked return value vulnerability. From a defensive standpoint, this class of bug is dangerous precisely because it fails open: when a security-critical function returns an error condition that the caller never validates, the application proceeds as if the operation succeeded. In practice, this pattern enables attackers to bypass validation logic — authentication checks, input sanitization, or integrity verification — by forcing the vulnerable function into its unhandled error path.
A CVSS of 9.2 reflects network reachability, no authentication requirement, and high impact to confidentiality and integrity. Combined with the observed campaign, the practical result is unauthenticated remote code execution or authorization bypass leading to web shell deployment on the storefront.
The PolyShell Attack Chain
Based on the observed campaign, the attack flow defenders should model is:
- Initial exploitation — The attacker sends crafted requests to the vulnerable Adobe Commerce/Magento component, triggering the unchecked return value condition to bypass a security control.
- Web shell deployment ("PolyShell") — A PHP-based web shell is written to a web-accessible directory. On Magento, the classic drop zones are
pub/media/,var/,pub/static/, and thedownloader/directory, because these paths are writable by the web server user and directly reachable over HTTP. - Persistence and hands-on-keyboard activity — The web shell is used to spawn system commands via PHP (
system(),exec(),shell_exec(),passthru()), dump theapp/etc/env.phpdatabase credentials, access the customer and order tables, and plant card-skimming JavaScript in checkout templates or core JS files. - Brotli-linked traffic — Unusual traffic involving the Brotli decoder has emerged alongside the campaign, consistent with attacker infrastructure exchanging compressed payloads with the implants and/or probing for the second KEV-listed Brotli flaw. Treat anomalous
Content-Encoding: brresponses or requests to your storefront as a hunt lead, not proof of compromise on its own.
Exploitation Status
- CISA KEV: Confirmed. Both Adobe Commerce/Magento vulnerabilities and the Brotli decoder flaw are in the KEV catalog as of this week.
- Active exploitation: Confirmed. Hundreds of stores breached in the PolyShell campaign.
- Federal remediation deadline: Federal Civilian Executive Branch agencies are bound by CISA Binding Operational Directive 22-01 to remediate KEV entries, typically within three weeks of listing. Check the KEV catalog entry for the exact due date — and treat that date as your own ceiling, not your target, regardless of whether BOD 22-01 applies to you.
Detection & Response
The detections below are tuned to the observed behaviors: web shell files in Magento-writable directories, the PHP interpreter spawning shell commands, and suspicious web request patterns. Deploy them, then hunt retroactively — with hundreds of stores already breached, assume exploitation attempts against your infrastructure have already occurred and look backward at least 30 days.
Sigma Rules
---
title: PHP Web Server Process Spawning Shell or System Commands
description: Detects the web server or PHP interpreter (Apache, nginx, php-fpm) spawning a shell or common post-exploitation tools — consistent with PolyShell web shell command execution on Adobe Commerce/Magento servers.
references:
- https://thehackernews.com/2026/10/adobe-commerce-polyshell-attacks-breach.html
- https://attack.mitre.org/techniques/T1059/
- https://attack.mitre.org/techniques/T1505/003/
author: Security Arsenal
date: 2026/10/21
status: experimental
id: 4f6c2a91-8b3d-4e7f-9a1c-2d5e6f7a8b9c
tags:
- attack.persistence
- attack.t1505.003
- attack.execution
- attack.t1059.004
logsource:
category: process_creation
product: linux
detection:
selection_parent:
ParentImage|endswith:
- '/php-fpm'
- '/php-fpm8.1'
- '/php-fpm8.2'
- '/php-fpm8.3'
- '/apache2'
- '/httpd'
- '/nginx'
selection_child:
Image|endswith:
- '/sh'
- '/bash'
- '/dash'
- '/curl'
- '/wget'
- '/nc'
- '/ncat'
- '/python'
- '/python3'
- '/perl'
- '/base64'
condition: selection_parent and selection_child
falsepositives:
- Magento cron jobs and message queue consumers legitimately invoking CLI tools
- Backup or deployment scripts executed under the web server context (investigate the parent chain)
level: high
---
title: PHP File Written to Magento Web-Accessible Directory
description: Detects creation of PHP files in Magento/Adobe Commerce directories that are web-reachable and commonly abused for web shell placement (pub/media, var, downloader, pub/static). Legitimate code deploys write PHP under app/code or vendor, not pub/media.
references:
- https://thehackernews.com/2026/10/adobe-commerce-polyshell-attacks-breach.html
- https://attack.mitre.org/techniques/T1505/003/
author: Security Arsenal
date: 2026/10/21
status: experimental
id: 8a1e3b52-6c4d-4f8a-b2e9-3c7d1a5f9e2b
tags:
- attack.persistence
- attack.t1505.003
logsource:
category: file_event
product: linux
detection:
selection_path:
TargetFilename|contains:
- '/pub/media/'
- '/pub/static/'
- '/var/importexport/'
- '/var/tmp/'
- '/downloader/'
- '/upload/'
selection_ext:
TargetFilename|endswith:
- '.php'
- '.phtml'
- '.php5'
- '.phar'
condition: selection_path and selection_ext
falsepositives:
- Some third-party Magento extensions legitimately generate .phtml in pub/static during static content deployment — baseline deployment windows and alert outside them
level: critical
---
title: Suspicious Web Request Patterns Against Magento Storefront
description: Detects inbound requests indicative of PolyShell exploitation and web shell interaction — direct POSTs to PHP files in media/static paths, requests with PHP function names or base64 payloads in parameters, and anomalous Brotli-encoded probes.
references:
- https://thehackernews.com/2026/10/adobe-commerce-polyshell-attacks-breach.html
- https://attack.mitre.org/techniques/T1190/
- https://attack.mitre.org/techniques/T1505/003/
author: Security Arsenal
date: 2026/10/21
status: experimental
id: 2b7d4e61-9f5a-4c8b-a3d1-6e2f8a4c7b3d
tags:
- attack.initial_access
- attack.t1190
- attack.persistence
- attack.t1505.003
logsource:
category: webserver
detection:
selection_webshell_access:
cs-method: 'POST'
cs-uri-stem|contains:
- '/media/'
- '/static/'
- '/downloader/'
cs-uri-stem|endswith:
- '.php'
- '.phtml'
selection_exploit_params:
cs-uri-query|contains:
- 'base64_decode'
- 'shell_exec'
- 'passthru'
- 'eval('
- 'assert('
- 'gzinflate'
- 'str_rot13'
condition: 1 of selection_*
falsepositives:
- Rare; legitimate storefront traffic does not POST to PHP files under media/static
- Security scanners and authorized penetration tests — verify source before dismissing
level: high
KQL Hunt — Microsoft Sentinel / Defender
This query hunts across web server logs (ingested via CEF/Syslog from nginx/Apache or WAF) for web shell interaction and exploitation probes, and separately across endpoint telemetry for the web-server-spawns-shell behavior. Run both over a 30-day lookback.
// Part 1: Web shell interaction and exploit probes in web/WAF logs
let lookback = 30d;
let suspicious_params = dynamic(["base64_decode","shell_exec","passthru","eval(","assert(","gzinflate","str_rot13","system("]);
CommonSecurityLog
| where TimeGenerated > ago(lookback)
| where DeviceProduct has_any ("nginx","apache","iis","waf","imperva","f5") or AdditionalExtensions has "br"
| extend Uri = coalesce(RequestURL, tostring(split(AdditionalExtensions, "request=")[-1]))
| where RequestMethod == "POST"
and (Uri has_any ("/media/", "/static/", "/downloader/") and Uri endswith_any (".php", ".phtml"))
or Uri has_any (suspicious_params)
| project TimeGenerated, SourceIP, DestinationHostName, RequestMethod, Uri, RequestClientApplication, DeviceAction
| order by TimeGenerated desc;
// Part 2: Web server / PHP-FPM spawning shells (endpoint telemetry)
DeviceProcessEvents
| where TimeGenerated > ago(lookback)
| where InitiatingProcessFileName has_any ("php-fpm", "apache2", "httpd", "nginx", "php")
| where FileName in~ ("sh", "bash", "dash", "curl", "wget", "nc", "ncat", "python", "python3", "perl", "base64")
| project TimeGenerated, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, FileName, ProcessCommandLine, AccountName
| order by TimeGenerated desc;
// Part 3: New PHP files in Magento web-accessible directories
DeviceFileEvents
| where TimeGenerated > ago(lookback)
| where FolderPath has_any ("/pub/media/", "/pub/static/", "/var/importexport/", "/downloader/")
| where FileName endswith_any (".php", ".phtml", ".php5", ".phar")
| where ActionType in ("FileCreated", "FileModified", "FileRenamed")
| project TimeGenerated, DeviceName, FolderPath, FileName, ActionType, InitiatingProcessFileName, InitiatingProcessCommandLine, SHA256
| order by TimeGenerated desc
Velociraptor VQL Hunt
Deploy this artifact against your Linux web servers to surface recently created or modified PHP files in Magento's web-reachable directories, plus any shells spawned by the web server process. In an incident, this gives you a fast fleet-wide sweep for PolyShell-style implants.
-- PolyShell / Magento web shell sweep: PHP files in web-accessible dirs + shells under web server processes
SELECT * FROM foreach(
row={
SELECT FullPath, Mtime, Ctime, Size
FROM glob(globs=[
'/var/www/**/pub/media/**/*.php',
'/var/www/**/pub/media/**/*.phtml',
'/var/www/**/pub/static/**/*.php',
'/var/www/**/downloader/**/*.php',
'/var/www/**/var/importexport/**/*.php',
'/var/www/**/var/tmp/**/*.php',
'/srv/**/pub/media/**/*.php'
])
WHERE Mtime > now() - 2592000
},
query={
SELECT FullPath, Mtime, Ctime, Size,
read_file(filename=FullPath, length=2048) AS FileHead
FROM scope()
})
-- Separately: enumerate processes and flag shells/tools whose parent is php-fpm/apache/nginx
LET procs = SELECT Pid, Ppid, Name, CommandLine, Exe, Username, CreateTime
FROM pslist()
SELECT Pid, Ppid, Name, CommandLine, Username, CreateTime
FROM procs
WHERE Name =~ '^(sh|bash|dash|curl|wget|nc|ncat|python3?|perl)$'
AND Ppid IN (SELECT Pid FROM procs WHERE Name =~ 'php-fpm|apache2|httpd|nginx')
Remediation & Verification Script (Linux)
Run this on each Adobe Commerce/Magento host. It checks patch posture, sweeps for likely web shells, verifies dangerous PHP functions are disabled, and confirms Brotli library versions. It does not replace applying the official Adobe patches — it buys you visibility and hardening while you schedule the patch window.
#!/bin/bash
# Security Arsenal - CVE-2026-111497 / PolyShell triage & hardening script
# Run as root or with sudo on each Magento/Adobe Commerce host.
set -u
echo "=== [1/6] Adobe Commerce / Magento version check ==="
MAGENTO_ROOT="${1:-/var/www/html}"
if [ -f "$MAGENTO_ROOT/bin/magento" ]; then
sudo -u www-data php "$MAGENTO_ROOT/bin/magento" --version 2>/dev/null || php "$MAGENTO_ROOT/bin/magento" --version
else
echo "[!] bin/magento not found at $MAGENTO_ROOT - pass the Magento root as arg 1"
fi
echo "=== [2/6] Sweep: PHP files modified in last 30 days in web-reachable dirs ==="
for d in pub/media pub/static downloader var/importexport var/tmp; do
if [ -d "$MAGENTO_ROOT/$d" ]; then
find "$MAGENTO_ROOT/$d" -type f \( -name '*.php' -o -name '*.phtml' -o -name '*.phar' \) -mtime -30 -printf '%TY-%Tm-%Td %TH:%TM %p\n'
fi
done
echo "=== [3/6] Sweep: known web shell signatures in web root ==="
grep -rIlE 'eval\s*\(\s*(base64_decode|gzinflate|str_rot13|gzuncompress)|shell_exec\s*\(|passthru\s*\(|assert\s*\(\s*\$_(GET|POST|REQUEST|COOKIE)' \
"$MAGENTO_ROOT" --include='*.php' --include='*.phtml' 2>/dev/null | head -50
echo "=== [4/6] Harden PHP: disable dangerous functions (verify current state) ==="
PHPINI=$(php -r 'echo php_ini_loaded_file();' 2>/dev/null)
echo "Loaded php.ini: ${PHPINI:-unknown}"
php -r 'echo "disable_functions = ", ini_get("disable_functions"), "\n";'
echo "RECOMMENDED: disable_functions = exec,passthru,shell_exec,system,proc_open,popen,show_source"
echo "Apply to both FPM and CLI pools, then: systemctl restart php*-fpm"
echo "=== [5/6] Block execution in media/static dirs (nginx snippet to apply) ==="
cat <<'EOF'
# Add to your nginx server block - PHP must never execute from these paths:
location ~* ^/(media|static|var|downloader)/.*\.(php|phtml|phar)$ { deny all; }
# Apache equivalent (.htaccess or vhost):
# <DirectoryMatch "(media|static|var|downloader)"> php_admin_flag engine off </DirectoryMatch>
EOF
echo "=== [6/6] Brotli library inventory (patch per your distro/vendor advisory) ==="
(ldconfig -p 2>/dev/null | grep -i brotli) || true
find /usr/lib /usr/local/lib -name 'libbrotli*' 2>/dev/null | head -20
nginx -V 2>&1 | tr ' ' '\n' | grep -i brotli || echo "nginx brotli module not detected or nginx absent"
echo "=== DONE. Review all hits above before declaring the host clean. ==="
Remediation
Act in this order. Speed matters more than elegance here — this is an active, KEV-listed campaign with hundreds of confirmed victims.
-
Patch immediately. Apply the security updates referenced in Adobe's security bulletin for Adobe Commerce and Magento Open Source covering CVE-2026-111497 and the second KEV-listed flaw. Pull the bulletin directly from the Adobe Security Bulletins page and verify the exact fixed version for your release line before deploying — do not rely on third-party summaries for version numbers. Update via Composer (
composer updatewith the patched package constraints) and runbin/magento setup:upgradefollowed by static content deployment. Confirm the installed version post-patch and record it for your KEV remediation evidence. -
Patch the Brotli decoder. Inventory everything that links
libbrotli— the script above gives you a starting list. Apply your OS distribution's updated brotli packages, and for statically linked or vendored copies (custom services, containers, CDN edge configurations), rebuild or redeploy with the fixed decoder. Containers are easy to forget: rebuild base images and roll deployments. -
Hunt before you trust. Patching closes the door; it does not evict an attacker already inside. Run the Sigma, KQL, and VQL content above with a minimum 30-day lookback on every storefront host. Any PHP file in
pub/media,pub/static,var/, ordownloader/that you cannot attribute to a known deployment is guilty until proven innocent — pull it, hash it, preserve it, and treat the host as compromised. -
If you find a web shell — assume full compromise. The shell had access to everything the web server user can read:
app/etc/env.php(database credentials, crypt key, admin URL), customer PII, and order data. Rotate all credentials (database, admin users, API keys, payment gateway secrets, crypt key), force admin password resets with 2FA enforcement, review admin accounts for unauthorized additions, and assess notification obligations — PCI-DSS forensic requirements and state breach notification laws likely apply if cardholder or customer data was accessible. Engage IR support before wiping anything. -
Harden the platform permanently.
- Disable PHP execution in
pub/media,pub/static,var, anddownloaderat the web server layer (snippet in the script above). - Set
disable_functionsto stripexec,shell_exec,system,passthru,proc_open, andpopenfrom the FPM pool. - Restrict the admin panel and
downloaderpath by IP allowlist or VPN; never leave them internet-exposed. - Deploy file integrity monitoring (AIDE, Wazuh, or commercial FIM) on the web root with alerting on PHP file creation outside deployment windows.
- Put the storefront behind a WAF with virtual patching rules for the exploit patterns above.
- Disable PHP execution in
-
Meet the CISA deadline. Federal agencies must remediate per BOD 22-01 — check the KEV entry for the due date. Private sector: treat the KEV due date as your SLA. Document remediation for auditors; KEV entries are increasingly referenced in cyber insurance and regulatory reviews.
Conclusion
PolyShell is a textbook example of why KEV additions must trigger an immediate, scripted response rather than a change-request queue. A CVSS 9.2 unchecked-return-value flaw in the platform that processes your customers' payments, actively exploited against hundreds of stores, is a drop-everything event. Patch, hunt backward, harden the execution surface, and if you find evidence of compromise, escalate to a full IR engagement — the difference between a patched vulnerability and a breached storefront is the web shell you didn't look for.
Related Resources
Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub
Is your security operations ready?
Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.