Skip to content

GitGuardian/s1ngularity-scanner

Repository files navigation

S1ngularity Scanner

A defensive security tool to detect potential compromise from the Nx "s1ngularity" supply chain attack.

About the Attack

The Nx s1ngularity attack was a sophisticated supply chain attack that compromised JavaScript developers through malicious packages in the Nx ecosystem. The attack targeted valuable credentials including:

  • GitHub tokens and SSH keys
  • npm authentication tokens
  • Environment variables containing API keys
  • Cryptocurrency wallet files
  • LLM client configurations (Claude, Gemini, ChatGPT)

Stolen credentials were exfiltrated to public GitHub repositories, resulting in over 2,300 distinct secrets being leaked from more than 1,000 compromised systems.

Scanner Purpose

This project relies on HasMySecretLeaked. To learn more about how this works, visit our What happens under the hood page.

Requirements

  • Python ≥3.9 (enforced at runtime)
  • ggshield - GitGuardian's CLI tool for secret scanning
  • uv (optional, recommended) - Modern Python package manager for better dependency isolation
  • GitHub CLI (optional) - for extracting GitHub tokens

Installation

Install ggshield

macOS:

# Using Homebrew (recommended)
brew install ggshield

# Or download standalone .pkg from GitHub releases (no Python required)

📦 Download .pkg from GitHub releases

Linux:

# Using pipx (recommended)
pipx install ggshield

# Or use distribution packages (deb/rpm) from Cloudsmith

📦 Download packages from Cloudsmith

Windows:

# Using Chocolatey
choco install ggshield

# Or download standalone .zip from GitHub releases (no Python required)

📦 Download .zip from GitHub releases

For more installation options, see the ggshield documentation.

Run the Scanner

Preferred approach with uv (recommended):

First, install uv for modern Python dependency management.

git clone https://github.com/GitGuardian/s1ngularity-scanner
cd s1ngularity-scanner
./leak_scanner.py

Alternative with Python directly:

macOS/Linux:

python3 leak_scanner.py

Windows:

python leak_scanner.py

Command Line Options

  • --min-chars <number> - Minimum character length for values to consider (default: 5)
  • --keep-temp-file - Keep the temporary file containing gathered values instead of deleting it
  • --timeout <seconds> - Maximum time to spend scanning filesystem for .env files (default: 0 for unlimited, set a number for time limit)
  • --verbose, -v - Show detailed scanning progress and debug information

How it works

Singularity Scanner uses environment variables and files, including files known to be used by the original exploit. We don't reuse the prompt as our analysis showed the AI didn't actually provide many files. Instead, the scanner directly targets known file locations and scans them for secrets. These secrets are hashed and compared against what GitGuardian found on GitHub.

The scanner collects potential secrets from these sources:

  • All environment variables from the current shell session
  • GitHub token from gh auth token command (if GitHub CLI is installed)
  • NPM configuration from $HOME/.npmrc
  • Environment files - all .env* files recursively found in your home directory
    • Skips hidden directories (starting with .) and node_modules for performance
    • Has a configurable timeout to prevent long scans on large filesystems

Security & Privacy

  • No data transmission: Secrets are never sent to GitGuardian or any external service
  • Local processing: All scanning happens locally on your machine
  • Hash comparison: Only SHA-256 hashes of potential secrets are compared against GitGuardian's database
  • Temporary files: A temporary file gg_gathered_values is created during scanning and automatically deleted (unless --keep-temp-file is used)

Examples

Basic scan with default settings:

./leak_scanner.py
# or: python3 leak_scanner.py

Scan with longer timeout for large filesystems:

./leak_scanner.py --timeout 120

Keep the temporary file for inspection:

./leak_scanner.py --keep-temp-file

Only consider longer values (reduces noise):

./leak_scanner.py --min-chars 10

Show detailed scanning progress:

./leak_scanner.py --verbose

Limited time scan (30 seconds):

./leak_scanner.py --timeout 30

Limitations

  • No AI queries: Unlike the original exploit, we don't ask Claude, Gemini or Q for files that may contain secrets
  • Filesystem scanning: Large filesystems may take time to scan completely. Use the timeout option e.g. --timeout 30 to limit the time spent scanning if needed
  • Directory exclusions: Hidden directories (.git, .cache, etc.) and node_modules are skipped for performance
  • Pattern matching: Only detects key-value assignments in standard formats (may miss unconventional secret storage)
  • False positives: May flag legitimate non-secret values that happen to match secret patterns

About

Scan for leaked secrets during the s1ngularity attack using GitGuardian HasMySecretLeaked

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •  

Languages