Magento Custom Options Hygiene (magento-custom-options-hygiene)
Summary
Magento-gated checks: custom_options path deny, PHP execution under that tree, and known PolyShell IoC filenames (no uploads).
Classification
- Category:
SECURITY - Plugin id:
magento-custom-options-hygiene - Version:
1.0.0 - Target types:
WEBSITE,WEBSHOP - Weight class:
LIGHT - Risk level:
HIGH - Browser required: No (HTTP / Node / other — see source)
- Tier / group: Tier 1 — HTTP-only
Schedule
- scheduleHints:
{ defaultInterval: '25 */6 * * *', priority: 3 } - Prerequisites: None declared on this plugin.
Configurable inputs
Public keys are derived from inputSchema: z.object({ ... }) (underscore-prefixed keys are runtime-only and omitted here).
| Field | Notes |
|---|---|
timeout |
Zod field in inputSchema — see source for defaults, min/max, and .describe(). |
requireMagento |
When true (default), skip neutrally if Magento fingerprints are absent. |
Runtime / injected config
- None documented beyond standard worker context (
target,config,logger,reportProgress). Underscore-prefixed keys are internal.
Checks that produce findings
These checks run inside this plugin during a single test run. They are not separate tests in the database — each becomes a Finding linked to the Run for magento-custom-options-hygiene.
| Check | Typical severity | Why |
|---|---|---|
Directory listing or open content under /media/custom_options/ (or /pub/media/...) |
CRITICAL | Uploaded custom-option files (including malware) are publicly fetchable — PolyShell blast radius. |
Missing-file probes return 200 under quote/ |
CRITICAL | The upload tree is serving paths that hardened configs deny entirely. |
| Magento site returns 404 instead of 403 on custom_options probes | WARNING | Deny-all is missing; existing uploads would be served. Soft signal, Magento-gated only. |
Missing .php / .phtml / .phar handled like executable scripts (PHP errors, X-Powered-By, 500 vs static 404) |
CRITICAL | Script execution under the upload path turns a file drop into RCE. |
Known PolyShell IoC filenames present under quote/{c1}/{c2}/{name} |
CRITICAL | Strong compromise indicator — webshells already on disk and web-reachable. |
Non-Magento targets are skipped (neutral) when requireMagento is true (default).
How each check works
- Magento gate — Homepage (and optional
/static/) fingerprints:Magento_*,mage/cookies,form_key,static/version*,x-magento-*headers. No match → skip. - Reachability — GET
/media/custom_options/,/quote/, and a random missing.pngunder Magento's nested quote layout. Classify as denied (403), missing (404/soft-404), accessible, or listing. - Script execution — Compare missing
.php/.phtml/.pharprobes to the static missing probe. Only strong handler signals create findings (no uploads). - IoCs — Probe Sansec/PolyShell filenames at
quote/{first}/{second}/{filename}. Flag only responses that look like real files (not soft-404 HTML). - No exploit — Never uploads files or exercises guest-cart custom-option APIs.
Caveats and concerns
- Not a CVE confirmer — Clean results mean the media path looks hardened / no known IoCs, not that Magento is patched against PolyShell.
- 404 ≠ safe — On Magento, 404 on this tree is WARNING (deny missing). True harden = 403.
- IoC list is finite — Random webshell names are not discovered; this catches common known names only.
- Script-exec is heuristic — Without a file on disk, absence of PHP-handler signals does not prove execution is impossible.
Source
packages/test-plugins/src/plugins/magento-custom-options-hygiene.ts