Skip to main content

Detect GlassWorm supply chain attack payloads - technique detection, not just blocklists

Project description

glassworm-hunter

Glassworm Hunter Logo

Detect GlassWorm supply chain attack payloads on your machine. Scans VS Code extensions, npm packages, Python packages, and git repositories.

This scanner detects the attack technique itself - invisible Unicode variation selector payloads, GlassWorm decoder patterns, C2 indicators, and credential harvesting code.

Install

pip install glassworm-hunter

Or with pipx:

pipx install glassworm-hunter

Quick start

Scan your current directory without scanning VS Code/Cursor extensions:

glassworm-hunter scan --no-extensions

Scan a specific project:

glassworm-hunter scan /path/to/project

What it detects

Technique detection (catches unknown variants)

  • Invisible Unicode payloads - variation selector characters (U+FE00-FE0F, U+E0100-E01EF) used to encode hidden code. Legitimate uses are 1-2 characters for emoji. GlassWorm uses thousands.
  • GlassWorm decoder patterns - the codePointAt + variation selector range arithmetic that decodes invisible payloads
  • Bidirectional override characters - Trojan Source attack (CVE-2021-42574)
  • Hangul filler - invisible valid JavaScript identifiers (U+3164)
  • eval/Function with dynamic content - execution sinks fed by decoded strings
  • Credential access - code reading .npmrc, .gitcredentials, SSH keys, token env vars
  • C2 communication patterns - Solana RPC calls, Google Calendar URLs, WebRTC data channels in unexpected contexts

Known IOC matching (supplementary)

  • 21 known malicious VS Code/OpenVSX extension IDs (all 5 waves)
  • 4 known malicious npm packages
  • 14 known C2 IP addresses
  • 3 known Solana C2 wallet addresses
  • Attacker email and build path artifacts

Severity levels

Level Meaning
CRITICAL Active GlassWorm payload detected (invisible Unicode cluster in code, decoder pattern)
HIGH Known malicious IOC matched (C2 IP, wallet, extension dependency on known malware)
MEDIUM Suspicious pattern worth reviewing (eval + dynamic content, credential access, Trojan Source)
LOW Informational (unusual zero-width character density, suspicious install scripts)

CLI options

glassworm-hunter scan [OPTIONS] [PATHS...]
Option Default Description
--extensions / --no-extensions on Scan VS Code/Cursor/Codium extensions
--npm-scan / --no-npm-scan on Scan node_modules
--pip-scan / --no-pip-scan off Scan Python site-packages
--git / --no-git on Scan git repositories
--format [console|json|sarif] console Output format
--output FILE stdout Write report to file
--severity [critical|high|medium|low] low Minimum severity to report
--max-file-size SIZE 10MB Skip files larger than this
--include-hidden off Scan hidden files/directories
--quiet off Suppress progress output
--verbose off Show every file being scanned
--exclude PATTERN Glob patterns to exclude (repeatable)
--disable-rule RULE_ID Suppress specific detection rules (repeatable)
--ioc-file FILE Load additional IoC indicators from a JSON file

A Rich progress bar is shown on stderr during scanning. It is automatically suppressed with --quiet or --verbose. A summary line (files scanned, findings, output path) is always printed to stderr after the scan completes.

Other commands

# List all detection rule IDs (for use with --disable-rule)
glassworm-hunter rules

# Update local IoC database from GitHub (default source:
# https://raw.githubusercontent.com/afine-com/glassworm-hunter/main/data/ioc.json)
glassworm-hunter update

# Update from a custom source (e.g. internal threat intelligence server)
glassworm-hunter update --source https://internal.corp/ioc.json

# Force overwrite existing local IoC database
glassworm-hunter update --force

# Print version
glassworm-hunter version

Exit codes

Code Meaning
0 No findings
1 Findings detected
2 Scanner error

If you find something

  1. Don't panic. The scanner found an indicator, not a confirmed breach.
  2. Don't execute the flagged code. Don't run, build, or test the affected project until resolved.
  3. CRITICAL findings: Uninstall the extension/package immediately. Rotate your NPM tokens, GitHub tokens, SSH keys, and any other credentials on the machine.
  4. HIGH findings: Investigate the flagged file. If it's in a dependency you didn't explicitly install, remove it.
  5. MEDIUM findings: Review the code. These patterns are suspicious but may be legitimate in some contexts.

CI/CD integration

JSON output for automated processing:

glassworm-hunter scan . --format json --output report.json --no-extensions

SARIF for GitHub Code Scanning:

glassworm-hunter scan . --format sarif --output results.sarif --no-extensions

Upload SARIF to GitHub:

- uses: github/codeql-action/upload-sarif@v3
  with:
    sarif_file: results.sarif

Use exit codes in CI:

glassworm-hunter scan . --severity critical --no-extensions || exit 1

Exclude build artifacts and vendor code:

glassworm-hunter scan . --exclude "dist/**" --exclude "*.min.js" --no-extensions

No network access

This scanner is fully offline by default. It reads local files only. No telemetry, no phone-home, no automatic update checks. IoC databases are bundled in the package.

The only command that makes a network request is glassworm-hunter update, which fetches the latest IoC database from GitHub (or a custom --source URL). It is never called automatically.

Configuration file

Place a .glassworm.yml in your project root to set defaults:

exclude:
  - "*.min.js"
  - "vendor/**"
  - "dist/**"

disable_rules:
  - zero-width-chars

severity: medium

CLI flags override config file values.

Custom IoC files

Use --ioc-file to load additional indicators from a JSON file. This is useful for team-specific or internal threat intelligence:

glassworm-hunter scan /path --ioc-file /path/to/team_ioc.json

The file must follow the same schema as data/ioc.json:

{
  "schema_version": "1.0",
  "extensions": [{"id": "publisher.name"}],
  "npm_packages": [{"name": "pkg", "malicious_versions": "1.0.0"}],
  "c2_ips": [{"ip": "1.2.3.4"}],
  "c2_wallets": [{"address": "..."}],
  "attacker_artifacts": [{"type": "email", "value": "attacker@example.com"}]
}

The custom file is merged on top of all other IoC layers (hardcoded → bundled → user ~/.glassworm/ioc.json--ioc-file).

IoC database layers

The scanner uses a 3+1 layer IoC system (each layer merges on top of the previous, never removes):

  1. Hardcoded — built into the Python source, always available
  2. Bundleddata/ioc.json shipped with the package
  3. User~/.glassworm/ioc.json, updated via glassworm-hunter update
  4. Custom--ioc-file flag, highest priority

Credits

  • Koi Security - original discovery of GlassWorm (October 2025) and ongoing tracking across multiple waves, including the OpenVSX/VSCode campaign, Rust binary pivot, and macOS pivot. IoC data in this scanner builds on their published research.
  • Aikido Security - analysis of the March 2026 GlassWorm wave targeting GitHub repositories and npm packages, alongside Socket, Step Security, and the OpenSourceMalware community.
  • AFINE - this scanner

Windows

The scanner works on Windows. 4 tests fail unless you run an elevated (Administrator) command prompt.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

glassworm_hunter-1.0.0.tar.gz (130.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

glassworm_hunter-1.0.0-py3-none-any.whl (43.0 kB view details)

Uploaded Python 3

File details

Details for the file glassworm_hunter-1.0.0.tar.gz.

File metadata

  • Download URL: glassworm_hunter-1.0.0.tar.gz
  • Upload date:
  • Size: 130.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for glassworm_hunter-1.0.0.tar.gz
Algorithm Hash digest
SHA256 5234f8f79138efaf012e8339819c99211b1be1d49b36a1ce0133afefab59f4c8
MD5 42c6ab5005aac345f67ee0295163f837
BLAKE2b-256 256cc1f0aafb5d63fc21f9f15e033bbdb6e8c89cf67bceb04218f8ccafcd5c6d

See more details on using hashes here.

Provenance

The following attestation bundles were made for glassworm_hunter-1.0.0.tar.gz:

Publisher: publish.yml on afine-com/glassworm-hunter

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file glassworm_hunter-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for glassworm_hunter-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a3914db8101a3c1d0bf86ea79b47d95825250b71fd875a55a9625441365827c3
MD5 5ccb8b1f2cc5dcf93ead2e0e6dea9bf5
BLAKE2b-256 920f7302fa0150e338bc76ab640386594e6bfa6b438107a08bf78613e85d4ffd

See more details on using hashes here.

Provenance

The following attestation bundles were made for glassworm_hunter-1.0.0-py3-none-any.whl:

Publisher: publish.yml on afine-com/glassworm-hunter

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page