Skip to content
Docs · v2026.05

Overview

EcomScan is a realtime detection & response platform for ecommerce storefronts. It deploys as a lightweight CLI agent on your server, scans your codebase for Magecart skimmers, webshells, backdoors, and obfuscated malware, then streams results to a central dashboard with alerting, MITRE ATT&CK mapping, and AI-powered remediation.

3 minutes to first scan: install the CLI (1 min), activate your license (1 min), and run your first scan (1 min). Everything else is configuration.

Architecture


  ┌─────────────┐       ┌──────────────┐       ┌────────────────┐
  │  Storefront  │       │  ecomscan    │       │   Dashboard    │
  │  /var/www/   │──────▶│  CLI agent   │──────▶│   + API        │
  │              │ scan  │              │ POST  │                │
  └─────────────┘       └──────────────┘       └────────────────┘
                         │ Signature engine      │ Alerts
                         │ Hash engine           │ Incidents
                         │ YARA rules            │ Threat intel
                         │ Heuristic engine      │ Compliance
                         │ Delta detection       │ Webhooks
                         │ Attack chain          └────────────────
                         └──────────────

Install the CLI

The ecomscan CLI runs on Linux (x86_64 / arm64), macOS, and WSL. Install with a single command:

# Install ecomscan CLI
$ curl -fsSL https://api.hbgdevlab.com/api/v1/cli/install.sh | sh -s -- --key=ec_key_xxxxx

# Or with wget
$ wget -qO- https://api.hbgdevlab.com/api/v1/cli/install.sh | sh -s -- --key=ec_key_xxxxx

Manual install

# Download binary directly
$ wget https://api.hbgdevlab.com/releases/ecomscan-linux-amd64
$ chmod +x ecomscan-linux-amd64
$ sudo mv ecomscan-linux-amd64 /usr/local/bin/ecomscan
$ ecomscan --version

Verify installation

$ ecomscan --version
ecomscan v1.0.4 (build: 2026-05-13, commit: a8f3c2d)

$ ecomscan status
  CLI:        v1.4.2
  API:        connected (https://api.hbgdevlab.com)
  License:    EC-GROW-**** (Growth tier)
  Auth:       authenticated as user@company.com

Quick start

Step 1: Authenticate

$ ecomscan auth login
  Email: user@company.com
  Password: ********
  ✓ Authenticated. Token saved to ~/.ecomscan/credentials.json

Step 2: Run a local scan

$ ecomscan scan --path /var/www/html --platform magento

  ▸ Scanning /var/www/html (magento)
  ▸ 15,241 files scanned in 12.3s
  ▸ Engines: signature ✓  hash ✓  heuristic ✓  YARA ✓  delta ✓

  ┌─────────────────────────────────────────────────────────┐
  │  RISK SCORE: 78/100 (CRITICAL)                         │
  │  Findings:  2 critical · 3 high · 1 medium · 0 low      │
  └─────────────────────────────────────────────────────────┘

  CRITICAL  Magecart · KeepUp.v3          /checkout/js/bundle.min.js
  CRITICAL  PHP webshell · WSO 4.0        /pub/media/.thumbs/x.php
  HIGH      Obfuscated eval chain         /app/code/local/helper.php
  HIGH      Exfil POST to 185.234.72.19  /skin/frontend/loader.js
  HIGH      XOR-encoded payload          /var/tmp/.cache.php
  MEDIUM    Unsigned 3rd-party script    /checkout/head.phtml

Step 3: Upload to dashboard

Uploading scan results requires an agent secret (ec_key_...), not your login JWT. Create one from the dashboard (API Keys → Create key) or during install:

# Create an API key from the dashboard (API Keys → Create key)
# Then scan + upload using the agent secret
$ ecomscan --key=ec_key_xxxxx scan \
    --path /var/www/html \
    --platform magento \
    --upload

  ✓ 6 findings uploaded to dashboard
  ✓ 2 alerts created (CRITICAL, HIGH)
Auth modes: ecomscan auth login gives you a JWT for CLI commands (keys, whoami). Scan upload uses the --key flag with an ec_key_... token scoped to a specific store.

Step 4: Start continuous monitoring

# Watch for file changes in real time
$ ecomscan monitor --path /var/www/html --platform magento

  ▸ Baseline created: 15,241 files hashed
  ▸ Watching /var/www/html for changes...
  ▸ Next scheduled scan: 6h0m0s
  ▸ Heartbeat: every 60s → api.hbgdevlab.com

License activation

After purchasing a plan you receive a license key. The prefix determines your tier:

PrefixTierStoresFeatures
EC-STAR-****Starter1Scan, monitor, alerts
EC-GROW-****Growthup to 10+ YARA, IOC feed, API
EC-AGCY-****AgencyUnlimited+ Multi-tenant, white-label
EC-ENTR-****EnterpriseUnlimited+ SSO, RBAC, custom MITRE
# Install with your API key — license is validated automatically
$ curl -fsSL https://api.hbgdevlab.com/api/v1/cli/install.sh | sh -s -- --key=ec_key_xxxxx

  ✓ Binary installed to ~/.ecomscan/bin/ecomscan
  ✓ API key saved to ~/.ecomscan/credentials.json
  ✓ Background monitoring active (systemd: ecomscan-agent)

Your first scan

What happens during a scan:

TimePhaseWhat happens
0-2sDiscoveryWalk filesystem, filter by extension, skip excludes
2-8sSignature + hashMatch against 500+ signatures and known-bad hashes
8-12sYARA + heuristicsYARA rules fire, then behavioral analysis on every file
12-15sDelta + scoringCompare against baseline, compute risk score per finding
15sReportGenerate unified report with family classification, MITRE mapping

Routing alerts

Every detection produces an alert. Configure destinations in the dashboard under Integrations:

  • Slack — channel per severity with rich alert cards.
  • Webhook — signed payload (HMAC-SHA256), retried with exponential backoff.
  • Email — per-incident alerts via SMTP or SendGrid.

Config file

The CLI reads config from ~/.ecomscan/config.yaml (or /etc/ecomscan/config.yaml for system-wide). All fields are optional — sensible defaults are applied.

# ~/.ecomscan/config.yaml

agent:
  store_id: "550e8400-e29b-41d4-a716-446655440000"
  secret_key: "ec_key_xxxxx"

api:
  endpoint: "https://api.hbgdevlab.com"
  timeout: 30s
  retry_max: 3

scanner:
  store_paths:
    - /var/www/html
  platform: magento
  scan_interval: 6h
  max_concurrency: 4
  enable_heuristics: true
  enable_yara: true
  extensions:
    - .php
    - .phtml
    - .js
    - .html
    - .xml
  exclude_paths:
    - node_modules
    - vendor
    - .git

monitor:
  enabled: true
  heartbeat_interval: 60s
  change_detection: true

Manage config via CLI

$ ecomscan config show                # View current config
$ ecomscan config set scan.concurrency 8   # Update a value
$ ecomscan config reset               # Reset to defaults

Environment variables

Every config key can be set as an env var with the ECOMSCAN_ prefix. Env vars override the config file.

# Required for agent mode
export ECOMSCAN_AGENT_STORE_ID="your-store-uuid"
export ECOMSCAN_AGENT_SECRET_KEY="ec_key_xxxxx"
export ECOMSCAN_API_ENDPOINT="https://api.hbgdevlab.com"

# Optional overrides
export ECOMSCAN_SCANNER_PLATFORM="magento"
export ECOMSCAN_SCANNER_STORE_PATHS=""/var/www/html""

Agent daemon mode

The agent daemon runs continuously — scanning on a schedule, monitoring file changes, and sending heartbeats to the API.

# Start the agent daemon
$ ecomscan monitor \
    --path /var/www/html \
    --platform magento \
    --scan-interval 6h

# What the daemon does:
  1. Creates filesystem baseline (SHA256 per file)
  2. Watches for file modifications via fsnotify
  3. Runs full scan every 6h (configurable)
  4. Sends heartbeat to API every 60s
  5. Picks up "Run scan" commands from dashboard
  6. Uploads findings + change events automatically

Data flow


  Agent daemon                         API server
  ────────────                         ──────────
  Heartbeat (60s)  ──────────────────▶ POST /api/v1/agents/heartbeat
  Scan results     ──────────────────▶ POST /api/v1/scans/results
  File changes     ──────────────────▶ POST /api/v1/events/file-change

  Auth header: X-Agent-Secret: ec_key_xxxxx

Deploy as a service

systemd (Linux)

# /etc/systemd/system/ecomscan.service

[Unit]
Description=ecomscan agent
After=network.target

[Service]
Type=simple
User=ecomscan
ExecStart=/usr/local/bin/ecomscan monitor --path /var/www/html --platform magento
Restart=always
RestartSec=10
Environment=ECOMSCAN_AGENT_SECRET_KEY=ec_key_xxxxx
Environment=ECOMSCAN_AGENT_STORE_ID=your-store-uuid

[Install]
WantedBy=multi-user.target
$ sudo systemctl enable --now ecomscan
$ sudo systemctl status ecomscan
$ sudo journalctl -u ecomscan -f             # tail logs

Magento & Adobe Commerce

$ ecomscan scan --path /var/www/html --platform magento

Automatically scans: app/code, app/design, pub/static, pub/media, var, generated. Understands Magento module structure, detects admin path obfuscation, and monitors env.php changes.

WooCommerce

$ ecomscan scan --path /var/www/html --platform woocommerce

Scans wp-content/plugins, wp-content/themes, wp-includes. Monitors wp-config.php, .htaccess, and detects unauthorized plugins.

Shopware

$ ecomscan scan --path /var/www/html --platform shopware

Supports Shopware 5 and 6. Scans custom plugins, themes, and public/ assets.

Headless storefronts

$ ecomscan scan --path /app/dist --platform other \
    --extensions .js,.ts,.jsx,.tsx

For headless/custom builds, use --platform other and specify extensions. Heuristic and YARA engines work on any codebase.

How detection works

Every file passes through 6 detection engines in sequence. The unified pipeline normalizes, deduplicates, and scores all findings:


  File
   │
   ├──▶ 1. Signature engine     500+ regex patterns (webshells, skimmers, backdoors)
   ├──▶ 2. Hash engine           Known-bad MD5/SHA256 database
   ├──▶ 3. YARA engine           Community + ecomscan YARA rules
   ├──▶ 4. IOC matcher           Domain, IP, hash indicators from threat feeds
   ├──▶ 5. Heuristic engine      40+ behavioral signals (entropy, obfuscation, exfil)
   ├──▶ 6. Delta detector        Baseline diff — what changed since last scan?
   │
   ▼
  Unified Detection
   │
   ├──▶ Family classification    Match to 100+ known malware families
   ├──▶ Confidence calibration   Engine reliability × context × rule override
   ├──▶ Risk scoring             Evidence-weighted, path-aware, exploit-chain amplified
   ├──▶ MITRE ATT&CK mapping    Technique + tactic assignment
   └──▶ Attack chain             Kill-chain reconstruction across files

Magecart family detection

EcomScan tracks 28+ known Magecart families by fingerprint, plus behavioral classes:

  • KeepUp.v3 — Image pixel exfiltration, card form hooks
  • Inter / Inter2 — Injected via compromised 3rd-party scripts
  • Grelos — Payment form overlay with data interception
  • MakeFrame — Iframe-based card capture
  • FormJacker — Form submit intercept + exfil

Unknown skimmers are caught via co-occurrence scoring: if a JS file on a checkout page has 3+ signals (form listener + card selector + beacon exfil), it's flagged even with no known signature.

File integrity monitoring

The integrity engine builds a SHA-256 baseline of every file under the monitored paths. On each scan, it compares the current filesystem against the baseline and flags:

  • New files — unexpected files in web-accessible directories
  • Modified files — changed content, especially in checkout/payment paths
  • Deleted files — removed security controls or config files
  • Permission changes — files made world-writable or executable
# Create a baseline after a clean deploy
$ ecomscan baseline --path /var/www/html

  ✓ Baseline created: 15,241 files tracked
  ✓ Saved to: ~/.ecomscan/baseline.json

Heuristic engine

The heuristic engine scores 40+ behavioral indicators without signatures:

SignalScoreCatches
eval() + base64_decode chain+0.50Obfuscated PHP backdoors
Shannon entropy > 5.5+0.20Packed/encrypted payloads
XOR cipher loops+0.35XOR-encoded malware
sendBeacon / fetch POST+0.35JS exfiltration (Magecart)
Hidden iframes+0.45Drive-by injection
exec/system + $_GET/$_POST+0.50Remote code execution
Suspicious TLD (.su .xyz .tk)+0.40C2 domain communication
Low whitespace ratio (<2%)+0.20Minified/obfuscated code

Verdict: score ≥ 0.70 = malicious, ≥ 0.35 = suspicious, < 0.35 = clean.

Delta detection

Compares each scan against the previous baseline. These file changes are auto-flagged at HIGH confidence even with zero signature matches:

  • PHP file added to /uploads/ or /media/ — executable in unexpected location
  • Checkout JavaScript modified since last scan — potential skimmer injection
  • Core config changed (wp-config.php, env.php, .htaccess)
  • New cron job file — persistence mechanism

MITRE ATT&CK mapping

Every detection is mapped to MITRE ATT&CK techniques. The attack chain reconstructor builds kill-chain narratives across multiple findings:


  Initial Access ──▶ Execution ──▶ Persistence ──▶ Collection ──▶ Exfiltration
  T1195.002         T1059.007     T1505.003       T1056.003     T1041
  Supply chain      JavaScript    Web shell       Form capture  C2 channel

CLI reference

# Scanning
ecomscan scan --path <dir>              # Scan directory for malware
ecomscan scan --path <dir> --upload     # Scan + upload to dashboard
ecomscan scan --path <dir> --report X   # Generate incident report
ecomscan scan --path <dir> --email X    # Scan + email report via API
ecomscan scan --path <dir> --db-scan    # Include WordPress DB scan
ecomscan scan --path <dir> --full       # Force full rescan (skip cache)

# Monitoring (daemon mode)
ecomscan monitor --path <dir>           # File watching + scheduled scans + dashboard commands

# Auth
ecomscan auth login                     # Email/password login
ecomscan auth logout                    # Clear credentials
ecomscan auth whoami                    # Show current user

# API keys
ecomscan keys list                      # List API keys
ecomscan keys create --name "prod"       # Create agent API key
ecomscan keys revoke --key-id <id>       # Revoke API key

# Other
ecomscan version                        # Print version + YARA status

Scan command flags

FlagDefaultDescription
--path <dir>(required)Directory to scan
--platform <type>othermagento | woocommerce | prestashop | shopware | opencart | other
--severity <level>lowMinimum severity to report: critical | high | medium | low
--format <type>tableOutput format: table | json | csv
--output <file>stdoutWrite report to file
--uploadfalseUpload results to API
--store-id <uuid>Store ID (required with --upload)
--exclude <patterns>Comma-separated glob patterns to skip
--max-size <MB>10Max file size in MB
--concurrency <N>CPU countParallel scan workers
--verbosefalseDebug logging
--jsonfalseForce JSON output (alias for --format json)
--no-colorfalseDisable colored output

Report format

When using --format json, the scan produces this structure:

{
  "id": "scan-uuid",
  "store_id": "store-uuid",
  "started_at": "2026-05-13T04:18:00Z",
  "completed_at": "2026-05-13T04:18:12Z",
  "duration": "12.3s",
  "platform": "magento",
  "total_files": 15241,
  "scanned_files": 14800,
  "findings": [
    {
      "path": "/checkout/js/bundle.min.js",
      "severity": "critical",
      "confidence": 97,
      "type": "magecart",
      "family": "KeepUp.v3",
      "mitre": "T1056.003",
      "matches": [
        {
          "signature_name": "Magecart_KeepUp_v3_Loader",
          "line": 42,
          "matched_text": "addEventListener('change'...)",
          "remediation": "Remove injected script, block exfil domain at edge"
        }
      ],
      "heuristic": {
        "verdict": "malicious",
        "score": 0.92,
        "indicators": ["form-hook", "beacon-exfil", "card-selector"]
      }
    }
  ],
  "summary": {
    "critical": 2,
    "high": 3,
    "medium": 1,
    "low": 0,
    "risk_score": 78
  }
}

API

The EcomScan REST API uses two authentication modes:

Authentication

ModeHeaderUsed by
User JWTAuthorization: Bearer <jwt>Dashboard, CLI (ecomscan auth login), user-facing endpoints
Agent secretX-Agent-Secret: <ec_key_...>Deployed agents: heartbeat, scan upload, file-change events
Public(none)Auth routes (/auth/login, /auth/signup), license validation, health check

User JWT endpoints

MethodEndpointDescription
GET/api/v1/storesList all stores
POST/api/v1/storesRegister a new store
GET/api/v1/stores/:idGet store details
GET/api/v1/stores/:id/scansList scans for a store
POST/api/v1/stores/:id/scansTrigger a scan
GET/api/v1/scansList all scans (cross-store)
GET/api/v1/scans/:idGet scan detail
GET/api/v1/scans/:id/findingsGet scan findings
GET/api/v1/dashboard/summaryDashboard summary stats
GET/api/v1/incidentsList incidents
GET/api/v1/incidents/:idGet incident detail
GET/api/v1/alertsList alerts
POST/api/v1/alerts/:id/ackAcknowledge an alert
GET/api/v1/keysList agent API keys
POST/api/v1/keysCreate agent API key
GET/api/v1/auth/meCurrent user profile
GET/api/v1/settingsWorkspace settings
GET/api/v1/compliance/summaryCompliance score

Agent secret endpoints

MethodEndpointDescription
POST/api/v1/scans/resultsUpload scan results
POST/api/v1/agents/heartbeatAgent heartbeat (returns pending commands)
POST/api/v1/events/file-changeFile change event
GET/api/v1/threat-intel/feedDownload signed threat intelligence bundle
POST/api/v1/threat-intel/telemetryReport signature match telemetry

Example

# List critical incidents
$ curl https://api.hbgdevlab.com/api/v1/incidents?severity=critical \
  -H "Authorization: Bearer ec_sk_..."

{
  "data": [
    {
      "id": "INC-2391",
      "store_id": "acmegear.com",
      "title": "Magecart KeepUp.v3 on /checkout",
      "severity": "critical",
      "risk_score": 78
    }
  ]
}

Webhooks

Subscribe to events in Dashboard → Integrations → Webhook. Payloads are signed with HMAC-SHA256 using your shared secret.

Events: scan.completed, alert.created, incident.opened, incident.resolved, store.compromised, agent.offline, integrity.diff.

Verify the signature:

expected = HMAC-SHA256(shared_secret, request_body)
actual   = request.headers["X-Ecomscan-Signature"]
valid    = constant_time_compare(expected, actual)

Troubleshooting

Agent not connecting

# Check connectivity
$ ecomscan status

# Test API directly
$ curl -s https://api.hbgdevlab.com/healthz

# Verify credentials
$ cat ~/.ecomscan/credentials.json

# Run with debug logging
$ ecomscan scan --path /var/www/html --verbose

High false positive rate

  • Exclude vendor directories: --exclude node_modules,vendor,.git
  • Raise severity threshold: --severity high
  • Framework files are automatically down-weighted (×0.6 confidence)
  • Create a baseline after a clean deploy: ecomscan baseline --path /var/www/html

Scan too slow

  • Increase concurrency: --concurrency 8
  • Skip large files: --max-size 5 (5 MB limit)
  • Exclude non-critical paths: --exclude var/log,var/cache,media/catalog

Common errors

ErrorFix
NOAUTH: credentials not foundRun ecomscan auth login
license expiredRenew at ecom.hbgdevlab.com/billing
permission denied: /var/www/htmlRun as the web server user or use sudo
upload failed: store not foundVerify --store-id matches a store in your dashboard
YARA: rules compilation failedUpdate CLI: ecomscan update (rules ship with binary)
Need help? Join the community at community.ecomscan.io or reach out to support@ecomscan.io. Enterprise customers get a dedicated Slack channel.