Skip to content
EcomScan documentation

Overview

EcomScan is a server-side malware scanner and API-backed investigation platform for ecommerce hosts. The CLI agent scans files, optional platform databases, components, file changes, and supported host evidence, then uploads structured results to the dashboard. Remediation remains operator-controlled.

Required sequence: create a workspace and store, create a store-scoped agent key, install the CLI, then run the scan against a path the agent can read. Command output shown below is illustrative; counts and available engines come from the installed build and scanned host.

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       │ Integration delivery
                         │ 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 --scan-path=/var/www/html

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

Manual install

# Download through the public CLI release endpoint
$ curl -fL https://api.hbgdevlab.com/api/v1/cli/download/linux/amd64 -o ecomscan-linux-amd64
$ chmod +x ecomscan-linux-amd64
$ sudo mv ecomscan-linux-amd64 /usr/local/bin/ecomscan
$ ecomscan version

Verify installation

$ ecomscan version
ecomscan <release version>
yara: true or false
scoring: EMRS:1.1

$ ecomscan status
  Version:       <installed version>
  API:           healthy (https://api.hbgdevlab.com)
  Authenticated: yes or no

Quick start

Step 1: Authenticate

$ ecomscan auth login
  Email: user@company.com
  Password: ********
  ✓ Logged in as user@company.com
  Credentials saved to ~/.ecomscan/credentials.json

Login creates a user JWT for account commands such as keys, report, and auth whoami. It does not replace the store-scoped agent key used for scan uploads.

Step 2: Run a local scan

The quickest form takes a path directly. The platform is detected from the files on disk, so --platform is only needed to override it.

$ ecomscan /var/www/html

  ▸ Platform: magento2 (auto-detected)
  ▸ Scanning /var/www/html
  ▸ 15,241 files scanned
  ▸ Engines: signature ✓  hash ✓  heuristic ✓  YARA ✓  delta ✓

  ┌─────────────────────────────────────────────────────────┐
  │  RISK SCORE: 78/100 (HIGH)                              │
  │  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 203.0.113.19  /skin/frontend/loader.js
  HIGH      XOR-encoded payload          /var/tmp/.cache.php
  MEDIUM    Unsigned 3rd-party script    /checkout/head.phtml

Scan and email the report

--report accepts an email address or a file path. Given an address it emails the incident report (which requires --key so the scan can be uploaded first); given a path it writes the report to that file and needs no network access.

$ ecomscan --key ec_key_xxxxx --report you@company.com /var/www/html

  ▸ Platform: woocommerce (auto-detected)
  ✓ Results uploaded
  ✓ Incident report emailed to you@company.com

$ ecomscan --report ./incident.txt /var/www/html
  ✓ Incident report saved to ./incident.txt

Scan the database

Skimmers frequently live in the database rather than on disk, where a file-only scan cannot see them. --db-scan reads credentials from the store itself — wp-config.php for WordPress and WooCommerce, app/etc/env.php for Magento — and inspects the tables attackers use for persistence.

$ ecomscan --key ec_key_xxxxx scan --path /var/www/html --db-scan --upload

  ▸ Connecting to Magento database
  CRITICAL  Obfuscated script in core_config_data (design/head/includes)
  HIGH      Payment gateway endpoint points at an unknown host

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 create and save one with the CLI after logging in:

$ ecomscan keys create --name "production scanner" --store-id <store-uuid> --use
# 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 magento2 \
    --upload

  ✓ Results uploaded to API
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 magento2

  ▸ Baseline created: 15,241 files hashed
  ▸ Watching /var/www/html for changes...
  ▸ Scan schedule: managed by the dashboard
  ▸ Heartbeat: every 60s → api.hbgdevlab.com

License activation

A license key controls plan entitlements; an agent key authenticates one store’s scanner. They are different credentials. Activate a generated license with the setup command and include the tenant and store IDs if you also want setup to register an upload-capable agent.

$ ecomscan install \
    --license-key EC-GROW-XXXX-XXXX-XXXX \
    --tenant-id <tenant-uuid> \
    --store-id <store-uuid> \
    --scan /var/www/html
Do not infer entitlements from the prefix. The API’s license record is authoritative for validity, tier, feature list, expiry, and store limit. If the API cannot be reached, the CLI has a limited offline fallback for recognized key formats.

Understanding your first scan

What happens during a scan, in order. Duration depends almost entirely on how many files the store has — a large Magento installation takes minutes, not seconds.

StepPhaseWhat happens
1DiscoveryWalk filesystem, filter by extension, skip excludes
2Signature + hashMatch against the signature set and known-bad hashes
3YARA + heuristicsAvailable YARA rules and behavioral checks inspect supported file types
4Host checksPersistence, webroot exposure and running processes
5Delta + scoringCompare against baseline, compute risk score per finding
6ReportGenerate unified report with family classification, MITRE mapping

Alerts and integrations

Uploaded scans with qualifying findings create alerts; scans with critical or high findings also create incidents. The Integrations page configures credentials, tests connections, and sends manual test payloads:

  • Slack and Teams — validate webhooks and send a manual test card.
  • Webhook — send a signed manual test payload using HMAC-SHA256.
  • PagerDuty, Jira, Splunk, Datadog, and Elastic — validate credentials and send provider-specific manual tests.

Connected, non-sandbox integrations automatically receive their selected scan.completed, alert.created, store.compromised, and agent.offline events. Sandbox integrations only receive manual tests. Secret configuration fields are encrypted at rest and are never returned by the API after they are saved.

CLI configuration and credentials

The installer creates ~/.ecomscan/config.yaml for local setup metadata and ~/.ecomscan/credentials.json for user and agent credentials. A keyed install also records the store path used by background monitoring.

# ~/.ecomscan/config.yaml (installer-generated example)
api_url: https://api.hbgdevlab.com
auto_update: true
telemetry: true
scan:
  max_file_size: 10485760
  concurrency: 4
  exclude:
    - "*.log"
    - "*.sql"
    - "node_modules/**"
    - "vendor/**"
    - ".git/**"
scanner:
  store_paths:
    - /var/www/html
monitor:
  watch_paths:
    - /var/www/html
Runtime settings are flag-driven. For the public ecomscanbinary, pass scan and monitor options such as --platform, --exclude, --concurrency, and --scan-interval on the command line. The config command edits YAML, but it does not currently replace those runtime flags.

Manage config via CLI

$ ecomscan config show                # View current config
$ ecomscan config path                # Print its path
$ ecomscan config set smtp.host smtp.example.com # Local report email
$ ecomscan config reset               # Reset to defaults

Credentials are stored with mode 0600. Use ecomscan keys create --name "scanner" --store-id <uuid> --use to save a default agent key; do not print or share credentials.json when troubleshooting.

Environment variables

The install script recognizes installer-specific environment variables. The CLI uses explicit flags for its API URL, key, and scan settings; local SMTP delivery has its own environment variables.

# Installer controls
export ECOMSCAN_API_URL="https://api.hbgdevlab.com"
export ECOMSCAN_NO_MODIFY_PATH=1

# Only needed for scan --smtp-email
export ECOMSCAN_SMTP_HOST="smtp.example.com"
export ECOMSCAN_SMTP_PORT="587"
export ECOMSCAN_SMTP_USER="scanner@example.com"
export ECOMSCAN_SMTP_PASS="<secret>"
export ECOMSCAN_SMTP_FROM="scanner@example.com"

Agent daemon mode

The agent daemon runs continuously, monitors file changes, sends heartbeats, and executes scan commands from the API. When an agent key is configured, set the schedule on the store page in the dashboard; standalone monitors without an API connection use the local --scan-interval value.

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

# What the daemon does:
  1. Creates filesystem baseline (SHA256 per file)
  2. Watches for file modifications via fsnotify
  3. Receives scheduled scans from the API when connected
  4. Sends heartbeat to API every 60s
  5. Picks up "Run scan" commands from dashboard
  6. Uploads scan results when an agent key is configured

Data flow


  Agent daemon                         API server
  ────────────                         ──────────
  Heartbeat (60s)  ──────────────────▶ POST /api/v1/agents/heartbeat
  Scan results     ──────────────────▶ POST /api/v1/scans/results
  File changes     ───────▶ local monitor log; periodic scan uploads the resulting findings

  Agent auth: X-Agent-Secret plus request-signing headers on mutating requests

The official CLI adds the key ID, timestamp, nonce, body digest, and HMAC signature automatically. Production API deployments require those signing headers for mutating agent requests, so raw curl calls need to reproduce the signing algorithm. Agent credentials rotate automatically and are written atomically before the old token enters its short grace period.

Storefront monitoring

Filesystem scanning is the primary protection layer. Two optional store-level monitors cover browser-facing changes from the Store details page:

  • Remote storefront monitor — the API safely fetches the public storefront on your chosen interval and alerts when scripts or security headers change.
  • Checkout browser monitor — a small sensor reports script URLs, inline-script hashes, and CSP violations from real checkout pages.

The browser sensor does not collect form values, cookies, DOM content, or script source. Review and approve expected script changes from the store page. Completed scan reports can also be shared using revocable, expiring read-only links from Scans.

Honeypot sensors

A honeypot is a deliberately exposed store that captures live attacks. Nothing legitimate writes to one, so every file change is an attack artefact — there is no false-positive tuning and no customer data involved. Supplying an access log lets the sensor correlate each dropped file with the request that created it, which is what tells you how the attacker got in rather than only what they left behind.

$ ecomscan honeypot --path /var/www/html \
    --access-log /var/log/nginx/access.log --out ./captures

  ✓ Sensor armed — waiting for attacks
  ! ATTACK ARTEFACT wp-content/uploads/thumb.php (created, 29 bytes)
    vector: POST /wp-content/plugins/vuln/upload.php from 203.0.113.44

Only run this on an isolated host you intend to have compromised, with outbound traffic restricted at the firewall. A honeypot is a machine you are inviting attackers into, and an unrestricted one becomes someone else’s attack infrastructure.

Deploy with systemd (Linux)

The recommended installer command with both --key and --scan-path creates ecomscan-agent.service when systemd is available, or falls back to a six-hour cron scan. For a manual unit, run it as the same account whose ~/.ecomscan/credentials.json contains the agent key.

# /etc/systemd/system/ecomscan-agent.service

[Unit]
Description=ecomscan agent
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=ecomscan
Environment=HOME=/home/ecomscan
WorkingDirectory=/home/ecomscan/.ecomscan
ExecStart=/home/ecomscan/.ecomscan/bin/ecomscan monitor --path /var/www/html --platform magento2
Restart=on-failure
RestartSec=30
Nice=10
IOSchedulingClass=best-effort
IOSchedulingPriority=6
CPUWeight=25
IOWeight=25
NoNewPrivileges=true
ProtectSystem=strict
ReadWritePaths=/home/ecomscan/.ecomscan

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

Platform support

EcomScan can scan any supported source tree. Magento and WooCommerce have the deepest platform-specific checks. PrestaShop, Shopware, and Sylius add component inventory where reliable package metadata is available; all named platforms receive path-aware detection.

Magento & Adobe Commerce

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

Scanning the store root covers supported source files across the tree. Magento mode adds path-aware scoring for app/code, app/design, pub/static, pub/media, var, and generated; Composer module inventory and vulnerability checks; and structural integrity checks for unexpected executable files. Add --db-scan to inspect Magento configuration tables using app/etc/env.php.

WooCommerce

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

WooCommerce mode inventories plugins and themes, checks known vulnerabilities and outdated versions, and verifies WordPress core and WordPress.org package checksums by default. Premium or custom plugins remain unverified when no official checksum manifest exists. Use --db-scan to inspect WordPress options and related tables using wp-config.php.

Shopware & Sylius

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

Both platforms are auto-detected and use Composer metadata for core and plugin inventory, vulnerability matching, and platform-aware file scoring. Their database-specific and official checksum workflows are not yet as deep as Magento and WooCommerce.

PrestaShop & OpenCart

$ ecomscan scan --path /var/www/html --platform prestashop
$ ecomscan scan --path /var/www/html --platform opencart

Both platforms are auto-detected from their standard markers and receive path-aware file context. PrestaShop module metadata is inventoried when available. The current CLI does not provide database inspection or official checksum workflows for these platforms.

Headless storefronts

$ ecomscan scan --platform custom --path /app/dist

For headless or custom builds use scan --platform custom. Signature, heuristic, hash, and available YARA checks run over supported file types; platform-specific inventory, database, and integrity checks do not apply.

How detection works

Supported files are evaluated by the enabled engines. YARA runs only when the installed binary includes YARA support and the engine is enabled. The unified pipeline then normalizes, deduplicates, enriches, and scores the evidence:


  File
   │
   ├──▶ 1. Signature engine     Regex patterns for 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      Behavioural signals (entropy, obfuscation, exfil)
   ├──▶ 6. Delta detector        Baseline diff — what changed since last scan?
   │
   ▼
  Unified Detection
   │
   ├──▶ Family classification    Match evidence to built-in family indicators
   ├──▶ 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

The built-in classifier contains 18 malware families across Magecart, webshell, backdoor, cryptominer, skimmer, and dropper categories. Five are named Magecart families:

  • KeepUp — Image pixel exfiltration, card form hooks
  • Inter — Injected via compromised 3rd-party scripts
  • Grelos — Payment form overlay with data interception
  • MakeFrame — Iframe-based card capture
  • Magecart-G4 — Group 4 loader and exfil chain

Named classification requires at least two family indicators. Separate YARA rules cover KeepUp, Grelos, FakeSpark, Google Analytics impersonation, and generic form-jacking; signed intelligence bundles can also add signature, hash, YARA, and IOC evidence without replacing the CLI binary.

Unknown skimmers are also caught via co-occurrence scoring: three or more signals such as a form listener, card-field selector, checkout context, or beacon can create a heuristic finding without a named-family match.

Integrity and change detection

File integrity monitoring

Monitor mode builds a SHA-256 baseline for supported files under the watched paths and uses filesystem events to identify content changes. Scan mode separately stores its latest full-file state for incremental scanning and delta comparison.

  • Created files — suspicious when PHP appears in media/upload paths or a hidden file appears.
  • Modified files — suspicious in checkout/payment JavaScript, core config files, or after a large size increase.
  • Deleted files — recorded when a previously tracked path disappears.
# Create a baseline after a clean deploy
$ ecomscan baseline --path /var/www/html

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

Delta detection

Scan delta compares the current state with the previous comparable scan. Current built-in rules can create findings without a signature match for:

  • PHP or PHTML added to /uploads/ or /media/.
  • Checkout, payment, or one-page JavaScript modified since the last scan.
  • Core config changed, including wp-config.php, env.php, local.xml, or .htaccess.
  • New cron-related PHP/shell files or admin-user-related files outside known platform paths.

Scoring and MITRE mapping

Heuristic engine

The heuristic engine scores behavioural indicators without signatures. A representative subset:

SignalBase weightCatches
User input reaches exec/system/eval0.50Command execution and webshells
Shannon entropy > 5.5variablePacked/encrypted payloads
XOR cipher loops+0.35XOR-encoded malware
sendBeacon / fetch POST0.35 / 0.30JavaScript exfiltration
Hidden iframes+0.45Drive-by injection
Multiple encode/decode callsup to 0.45Obfuscation chains
Suspicious TLD (.su .xyz .tk)0.40–0.50C2 domain communication
Low whitespace ratio (<2%)+0.20Minified/obfuscated code

These are pre-calibration weights: noisy data paths, minified third-party JavaScript, and framework context can reduce them. The heuristic verdict is malicious at ≥ 0.70, suspicious at ≥ 0.35, and clean below 0.35. The final EMRS report is a separate 0–100 score with medium/high/critical thresholds at 40/70/90.

MITRE ATT&CK mapping

Known detection types are enriched with MITRE ATT&CK techniques. When mapped techniques exist across correlated detections, the scanner can build an attack-chain narrative:


  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 Magento/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" --store-id <uuid> --use # Create + save agent key
ecomscan keys revoke --key-id <id>       # Revoke API key

# Other
ecomscan baseline --path <dir>           # Build monitor baseline
ecomscan report --scan-id <uuid>         # Fetch API scan export
ecomscan status                          # API, auth, and engine status
ecomscan version                         # Print version + YARA status

Scan command flags

The flags below belong to ecomscan scan. The shorter ecomscan <path> form supports only --report, --email, --full, and --url, plus the global flags.

FlagDefaultDescription
--path <dir>(required)Directory to scan
--platform <type>auto-detectedmagento2 | woocommerce | prestashop | shopware | opencart | custom
--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 <value>localLocal scan-state namespace; upload scope comes from the agent key
--exclude <patterns>Comma-separated glob patterns to skip
--max-size <MB>10Max file size in MB
--concurrency <N>CPU countParallel scan workers
--db-scanfalseInspect supported Magento or WordPress databases
--fullfalseIgnore the incremental cache and rescan all files
--url <base-url>Check whether sensitive webroot files are publicly downloadable
--report <email|file>Email through EcomScan or write a SOC incident report
--email <addresses>Upload and email the report through EcomScan
--smtp-email <addresses>Email through SMTP configured on this host
--yaratrueUse YARA when supported by the installed binary
--yara-rules <dir>bundledLoad .yar rules from a directory
--no-plugin-auditfalseSkip plugin/theme or Magento module audit
--no-plugin-integrityfalseSkip WordPress checksum and Magento structural integrity checks
--plugin-integrity-strictfalseTreat soft WordPress checksum differences as issues
--wp-locale <locale>en_USWordPress core checksum locale
--limit <N>40Maximum table detections; 0 prints all
--vuln-limit <N>10Maximum plugin CVEs in table output; 0 prints all
--outdated-limit <N>10Maximum outdated components in table output; 0 prints all
--api-url <url>hosted APIGlobal API endpoint override
--key <secret>Global store-scoped agent key; alias: --token
--verbosefalseDebug logging
--jsonfalseForce JSON output (alias for --format json)
--no-colorfalseDisable colored output

Report format

When using --format json, the scan produces the unified report structure below (abbreviated; context, evidence, family, delta, platform audit, and host sections appear when available):

{
  "scan_id": "scan-uuid",
  "store_id": "store-uuid",
  "score_version": "EMRS:1.1",
  "platform": "magento2",
  "timestamp": "<RFC3339 timestamp>",
  "files_scanned": 14800,
  "risk_score": {
    "final_score": 78,
    "severity": "high",
    "score_version": "EMRS:1.1",
    "breakdown": { "signature_score": 45, "hash_score": 0 }
  },
  "detections": [
    {
      "id": "detection-uuid",
      "rule_id": "rule-id",
      "source": "signature",
      "file_path": "/var/www/html/pub/static/js/bundle.min.js",
      "family": "magecart",
      "type": "skimmer",
      "severity": "critical",
      "confidence": 0.97,
      "mitre_attack": ["T1056.003"]
    }
  ],
  "summary": {
    "total_detections": 1,
    "total_incidents": 1,
    "by_severity": { "critical": 1 }
  }
}

The report’s incidents and total_incidents are correlated evidence clusters produced inside that scan report. Dashboard incidents are separate API records created after an uploaded scan contains high or critical findings.

API and webhooks

The EcomScan REST API has three access categories:

Authentication

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

User JWT permissions follow four roles: viewer is read-only;analyst can run scans and work findings, alerts, incidents, and reports;admin also manages stores, keys, integrations, webhooks, and workspace policy;owner additionally manages billing. Cross-tenant operator routes also require the configured platform-admin tenant.

Selected user JWT endpoints

MethodEndpointDescription
GET/api/v1/storesList all stores
POST/api/v1/storesRegister a new store
GET/api/v1/stores/:store_idGet store details
GET/api/v1/stores/:store_id/scansList scans for a store
POST/api/v1/stores/:store_id/scansTrigger a scan
GET/POST/api/v1/stores/:store_id/checkout-monitorManage the checkout browser sensor
GET/POST/api/v1/stores/:store_id/remote-monitorManage remote storefront monitoring
GET/api/v1/scansList all scans (cross-store)
GET/api/v1/scans/:scan_idGet scan detail
GET/api/v1/scans/:scan_id/findingsGet scan findings
GET/POST/api/v1/scans/:scan_id/sharesManage expiring report links
GET/api/v1/findings/:finding_idGet one finding
PATCH/api/v1/findings/:finding_idUpdate finding status and notes
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/:alert_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/agents/refresh-tokenRefresh an agent token
POST/api/v1/agents/confirm-token-rotationConfirm a safely persisted replacement token
POST/api/v1/scans/:scan_id/email-reportEmail an uploaded scan report
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
POST/api/v1/threat-intel/unknownsReport metadata for unidentified suspicious files
POST/api/v1/threat-intel/honeypot-capturesSubmit honeypot capture artifacts

Example

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

{
  "data": [
    {
      "id": "incident-uuid",
      "store_id": "store-uuid",
      "title": "Critical scan findings detected",
      "severity": "critical",
      "priority": 1
    }
  ]
}

Webhooks

Generic alert webhooks and dashboard provider integrations are separate API surfaces. Webhooks registered with POST /api/v1/webhooks are automatically delivered for matching alert event types. The API returns the generated signing secret once when the webhook is created. Connected provider records under /api/v1/integrationsalso receive their selected automatic event types; sandbox records remain manual-test only.

$ curl -X POST https://api.hbgdevlab.com/api/v1/webhooks \
  -H "Authorization: Bearer <jwt>" \
  -H "Content-Type: application/json" \
  -d '{"name":"SOC receiver","url":"https://soc.example.com/ecomscan","events":["malware_critical","store_compromised"]}'

Verify the signature:

expected = "sha256=" + hex(HMAC-SHA256(shared_secret, raw_request_body))
actual   = request.headers["X-EcomScan-Signature"]
valid    = constant_time_compare(expected, actual)

The request also includes X-EcomScan-Event with the alert type.

Troubleshooting

Agent not connecting

# Check connectivity
$ ecomscan status

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

# Verify credential state without printing secrets
$ ecomscan auth whoami
$ ls -l ~/.ecomscan/credentials.json

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

High false positive rate

  • Inspect the complete evidence first: --format json --output scan.json.
  • Raise severity threshold: --severity high
  • Known framework paths are automatically down-weighted; verified integrity differences are not.
  • Use absolute path prefixes with --exclude, and avoid excluding vendor/ when you need vulnerable-library checks.
  • Mark reviewed findings ignored or resolved in the dashboard so analyst state is retained.

Scan too slow

  • Increase concurrency: --concurrency 8
  • Skip large files: --max-size 5 (5 MB limit)
  • Exclude known-safe generated paths with absolute prefixes, for example --exclude /var/www/html/var/export.

Common errors

ErrorFix
not authenticated - use --token or auth loginLog in for user-facing API commands
not authenticated - use --keyCreate a store-scoped key and pass --key or save it with keys create --use
API returned status 401/403Replace an expired or revoked key and verify its store scope
permission denied: /var/www/htmlRun as an account with read access to the store tree
path is not a directoryPass the storefront root to scan --path
YARA rules compilation failedCheck custom --yara-rules files, or update when using bundled rules
Need help? Reach out to support@ecomscan.io.