Detect AI-hallucinated package attacks before they compromise your supply chain.
The Problem β’ The Solution β’ Quick Start β’ VS Code β’ GitHub Action β’ CLI β’ API
Slopsquatting is a new class of supply chain attack that exploits AI code assistants. When developers use AI tools like ChatGPT, Claude, or Copilot to write code, these models sometimes "hallucinate" package names that don't exist.
# AI might suggest this code:
from flask_gpt_helper import create_ai_endpoint # This package doesn't exist!Attackers monitor package registries for these hallucinated names and register malicious packages before developers realize the package doesn't exist. When the developer runs pip install, they unknowingly install malware.
- AI Hallucination: Developer asks AI for help, AI suggests non-existent package
flask-gpt-helper - Attacker Registration: Attacker registers
flask-gpt-helperwith malicious code - Developer Installation: Developer runs
pip install flask-gpt-helper - Compromise: Malicious package executes, stealing credentials, injecting backdoors, or exfiltrating data
- 30%+ of AI-generated code contains package references that don't exist
- Typosquatting attacks have been successful for years; AI makes this worse
- Traditional security tools don't catch packages that look legitimate but are phantom attacks
- Once a malicious package is installed, the damage is done
Phantom Guard detects potentially dangerous packages before installation by analyzing:
| Detection Method | Description |
|---|---|
| Registry Verification | Checks if the package actually exists on PyPI, npm, or crates.io |
| Pattern Analysis | Identifies AI hallucination patterns like flask-gpt-helper, easy-requests, py-openai-utils |
| Typosquat Detection | Uses Levenshtein distance to find suspicious similarities to popular packages |
| Metadata Analysis | Flags packages with few downloads, recent creation, or missing maintainers |
| Multi-Signal Scoring | Combines 15 risk signals into a single actionable score |
pip install phantom-guard# Validate a single package
phantom-guard validate flask-gpt-helper
# Check your requirements file
phantom-guard check requirements.txt
# Validate npm packages
phantom-guard validate lodash-utils --registry npm
# Check Cargo.toml for Rust projects
phantom-guard check Cargo.toml$ phantom-guard validate flask-gpt-helper
Phantom Guard v0.2.0
Package: flask-gpt-helper
Registry: pypi
Status: HIGH RISK
Signals:
- Package not found on PyPI (weight: 0.90)
- Matches hallucination pattern: Popular package + AI + helper (weight: 0.85)
- Possible typosquat of 'flask' (distance: 2) (weight: 0.76)
Risk Score: 0.92
Recommendation: DO NOT INSTALL
Get real-time package validation directly in your editor. The VS Code extension highlights suspicious packages as you edit dependency files.
Install from VS Code Marketplace
Search for "Phantom Guard" in the VS Code Extensions marketplace, or:
code --install-extension phantom-guard.phantom-guard-vscode| Feature | Description |
|---|---|
| Real-time Validation | Validates packages as you type in dependency files |
| Inline Diagnostics | Shows warnings directly in the editor |
| Hover Information | Hover over package names to see risk details |
| Quick Fixes | One-click actions to ignore or investigate packages |
| Status Bar | Shows validation status at a glance |
requirements.txt(Python)package.json(npm)pyproject.toml(Python)Cargo.toml(Rust)
| Setting | Default | Description |
|---|---|---|
phantomGuard.enabled |
true |
Enable/disable validation |
phantomGuard.pythonPath |
auto | Path to Python with phantom-guard |
phantomGuard.threshold |
0.5 |
Risk score threshold (0.0-1.0) |
phantomGuard.ignoredPackages |
[] |
Packages to skip |
Automate dependency scanning in your CI/CD pipeline with the official GitHub Action.
# .github/workflows/phantom-guard.yml
name: Phantom Guard
on:
pull_request:
paths:
- 'requirements.txt'
- 'package.json'
- 'Cargo.toml'
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: matte1782/phantom-guard-action@v1
with:
files: |
requirements.txt
package.json
fail-on: suspicious| Input | Default | Description |
|---|---|---|
files |
auto-detect | Glob patterns for dependency files |
fail-on |
high_risk |
Fail threshold: suspicious or high_risk |
comment |
true |
Post results as PR comment |
sarif |
false |
Generate SARIF for Security tab |
The action automatically posts a summary comment on pull requests:
## Phantom Guard Scan Results
| Package | Registry | Risk | Score |
|---------|----------|------|-------|
| flask | pypi | SAFE | 0.02 |
| flask-gpt-helper | pypi | HIGH_RISK | 0.92 |
1 high-risk package detected. Review before merging.
Enable SARIF output to see results in GitHub's Security tab:
- uses: matte1782/phantom-guard-action@v1
with:
sarif: true
- uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: phantom-guard.sarifPhantom Guard validates packages across major package registries:
| Registry | File Types | Auto-Detection |
|---|---|---|
| PyPI (Python) | requirements.txt, pyproject.toml, Pipfile |
Yes |
| npm (JavaScript) | package.json |
Yes |
| crates.io (Rust) | Cargo.toml |
Yes |
Phantom Guard classifies packages into four risk levels:
| Level | Exit Code | Description | Action |
|---|---|---|---|
| SAFE | 0 | Package exists, no suspicious signals | Proceed with installation |
| SUSPICIOUS | 1 | Some risk signals detected | Review before installing |
| HIGH_RISK | 2 | Strong hallucination indicators | Do not install |
| NOT_FOUND | 3 | Package does not exist | Verify package name |
Phantom Guard analyzes packages for multiple risk indicators:
| Signal Type | Weight | Description |
|---|---|---|
NOT_FOUND |
0.90 | Package doesn't exist on registry |
HALLUCINATION_PATTERN |
0.30-0.85 | Matches known AI hallucination patterns |
TYPOSQUAT |
0.30-0.95 | Similar to popular package name |
NAMESPACE_SQUATTING |
0.70 | Mimics organization namespace (e.g., aws-, google-) |
DOWNLOAD_INFLATION |
0.60 | Suspicious download patterns detected |
OWNERSHIP_TRANSFER |
0.55 | Recent maintainer change on established package |
VERSION_SPIKE |
0.50 | Rapid version releases (5+ in 24 hours) |
RECENTLY_CREATED |
0.40 | Package created less than 30 days ago |
LOW_DOWNLOADS |
0.30 | Less than 1,000 downloads/month |
NO_REPOSITORY |
0.25 | No source repository linked |
NO_MAINTAINER |
0.30 | No maintainers listed |
FEW_RELEASES |
0.20 | Less than 3 releases |
SHORT_DESCRIPTION |
0.15 | Description under 10 characters |
POPULAR_PACKAGE |
-0.50 | Known popular package (reduces risk) |
LONG_HISTORY |
-0.20 | Package older than 1 year (reduces risk) |
| Command | Description |
|---|---|
validate <package> |
Validate a single package |
check <file> |
Check all packages in a dependency file |
cache clear |
Clear the local cache |
cache stats |
Show cache statistics |
cache path |
Display cache file location |
| Option | Short | Description |
|---|---|---|
--version |
-V |
Show version and exit |
--help |
Show help and exit |
phantom-guard validate <package> [OPTIONS]| Option | Short | Default | Description |
|---|---|---|---|
--registry |
-r |
pypi |
Target registry: pypi, npm, crates |
--verbose |
-v |
false |
Show detailed signal information |
--quiet |
-q |
false |
Show only the result |
--no-banner |
false |
Hide the banner | |
--plain |
false |
Disable colors (plain text output) |
phantom-guard check <file> [OPTIONS]| Option | Short | Default | Description |
|---|---|---|---|
--registry |
-r |
auto | Override registry detection |
--fail-on |
high_risk |
Exit non-zero on: suspicious, high_risk |
|
--ignore |
Comma-separated packages to skip | ||
--parallel |
10 |
Number of concurrent validations | |
--fail-fast |
false |
Stop on first HIGH_RISK package | |
--output |
-o |
text |
Output format: text, json |
--quiet |
-q |
false |
Minimal output |
--no-banner |
false |
Hide the banner | |
--plain |
false |
Disable colors |
# Verbose output with all signals
phantom-guard validate some-package -v
# Check requirements with JSON output
phantom-guard check requirements.txt -o json
# Fail on any suspicious package in CI
phantom-guard check requirements.txt --fail-on suspicious
# Skip known packages and run fast
phantom-guard check requirements.txt --ignore boto3,requests --parallel 20
# Stop immediately on first high-risk package
phantom-guard check requirements.txt --fail-fast
# Plain output for scripting
phantom-guard validate flask-helper --plain --quietAdd Phantom Guard to your CI pipeline to catch dangerous packages before they're installed:
# .github/workflows/security.yml
name: Security Check
on:
push:
paths:
- 'requirements.txt'
- 'pyproject.toml'
- 'package.json'
- 'Cargo.toml'
pull_request:
paths:
- 'requirements.txt'
- 'pyproject.toml'
- 'package.json'
- 'Cargo.toml'
jobs:
phantom-guard:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install Phantom Guard
run: pip install phantom-guard
- name: Scan Python dependencies
run: phantom-guard check requirements.txt --fail-on suspicious
- name: Scan JavaScript dependencies (if exists)
if: hashFiles('package.json') != ''
run: phantom-guard check package.json --fail-on suspiciousPrevent dangerous packages from being committed:
# .pre-commit-config.yaml
repos:
- repo: local
hooks:
- id: phantom-guard
name: Phantom Guard
entry: phantom-guard check
language: system
files: ^(requirements.*\.txt|pyproject\.toml|package\.json|Cargo\.toml)$
pass_filenames: trueInstall the hook:
pip install pre-commit
pre-commit install# .gitlab-ci.yml
phantom-guard:
stage: security
image: python:3.11
script:
- pip install phantom-guard
- phantom-guard check requirements.txt --fail-on suspicious
only:
changes:
- requirements.txt
- pyproject.tomlPhantom Guard provides a Python API for programmatic access.
import asyncio
from phantom_guard.core import validate_package, PackageRisk, Recommendation
async def check_package(name: str) -> None:
"""Validate a single package asynchronously."""
risk: PackageRisk = await validate_package(name, registry="pypi")
print(f"Package: {risk.name}")
print(f"Exists: {risk.exists}")
print(f"Risk Score: {risk.risk_score:.2f}")
print(f"Recommendation: {risk.recommendation.value}")
if risk.signals:
print("Signals:")
for signal in risk.signals:
print(f" - {signal.message} (weight: {signal.weight:.2f})")
# Take action based on recommendation
if risk.recommendation == Recommendation.HIGH_RISK:
print("WARNING: Do not install this package!")
elif risk.recommendation == Recommendation.SUSPICIOUS:
print("CAUTION: Review this package before installing.")
else:
print("OK: Package appears safe.")
asyncio.run(check_package("flask-gpt-helper"))from phantom_guard.core import validate_package_sync, Recommendation
# Synchronous wrapper for non-async code
risk = validate_package_sync("requests", registry="pypi")
if risk.recommendation == Recommendation.SAFE:
print(f"{risk.name} is safe to install")import asyncio
from phantom_guard.core import validate_batch
async def scan_requirements() -> None:
"""Scan multiple packages concurrently."""
packages = [
"flask",
"flask-gpt-helper", # Suspicious
"reqeusts", # Typosquat of 'requests'
"django",
"numpy",
]
results = await validate_batch(
packages,
registry="pypi",
concurrency=10, # Max parallel validations
)
for risk in results:
status = risk.recommendation.value.upper()
print(f"[{status:10}] {risk.name} (score: {risk.risk_score:.2f})")
asyncio.run(scan_requirements())from phantom_guard.core import validate_batch_sync
# Synchronous wrapper
results = validate_batch_sync(
["flask", "django", "pyramid"],
registry="pypi",
concurrency=5,
)
for result in results:
print(f"{result.name}: {result.recommendation.value}")from phantom_guard.core import detect_typosquat, check_typosquat
# Get signals for typosquat detection
signals = detect_typosquat("reqeusts", registry="pypi")
for signal in signals:
print(f"Typosquat detected: {signal.message}")
print(f" Target: {signal.metadata.get('target')}")
print(f" Similarity: {signal.metadata.get('similarity')}")
# Simple check returning best match
match = check_typosquat("numpyy", registry="pypi")
if match:
print(f"'{match.target}' might be the intended package (distance: {match.distance})")from phantom_guard.core import (
# Core types
PackageRisk, # Complete risk assessment
Signal, # Individual risk signal
Recommendation, # SAFE, SUSPICIOUS, HIGH_RISK, NOT_FOUND
SignalType, # NOT_FOUND, TYPOSQUAT, HALLUCINATION_PATTERN, etc.
# Functions
validate_package, # Async single package validation
validate_package_sync, # Sync single package validation
validate_batch, # Async batch validation
validate_batch_sync, # Sync batch validation
detect_typosquat, # Typosquat signal detection
)Phantom Guard is optimized for speed with an intelligent caching layer:
| Operation | Time | Condition |
|---|---|---|
| Single package (cached) | <10ms | P99 latency |
| Single package (uncached) | <200ms | P99 latency |
| 50 packages (batch) | <5s | P99, concurrent |
| Pattern matching | <1ms | P99, in-memory |
Results are cached locally to speed up repeated checks:
# Show cache location and size
phantom-guard cache path
# Display cache statistics
phantom-guard cache stats
# Clear entire cache
phantom-guard cache clear
# Clear only PyPI entries
phantom-guard cache clear --registry pypi| Variable | Default | Description |
|---|---|---|
NO_COLOR |
Disable colored output when set | |
PHANTOM_GUARD_CACHE_DIR |
Platform default | Override cache directory |
PHANTOM_GUARD_TIMEOUT |
30 |
API request timeout in seconds |
The cache is stored in a platform-specific location:
| Platform | Default Location |
|---|---|
| Linux | ~/.cache/phantom-guard/cache.db |
| macOS | ~/Library/Caches/phantom-guard/cache.db |
| Windows | %LOCALAPPDATA%\phantom-guard\cache.db |
Phantom Guard is designed with security as a priority:
| Principle | Implementation |
|---|---|
| No shell execution | All operations use Python libraries, never subprocess.call() with shell=True |
| No eval/exec | Package names and data are never executed as code |
| Input validation | All inputs are validated before processing |
| Minimal dependencies | Only well-established, audited dependencies |
| No network for patterns | Pattern matching is entirely local, no data exfiltration |
| Read-only registry access | Only reads public metadata, never writes or modifies |
Phantom Guard protects against:
- AI-hallucinated package names
- Typosquatting attacks
- Newly registered malicious packages
- Packages mimicking popular libraries
It does not protect against:
- Already-compromised legitimate packages
- Malicious code in established packages
- Supply chain attacks on dependencies of dependencies
We welcome contributions! Please see CONTRIBUTING.md for guidelines.
# Clone the repository
git clone https://github.com/matte1782/phantom_guard.git
cd phantom-guard
# Install with development dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Type checking
mypy src/
# Linting
ruff check src/# All tests
pytest
# Unit tests only (fast)
pytest -m unit
# Integration tests (requires network)
pytest -m integration
# With coverage
pytest --cov=phantom_guard --cov-report=htmlPhantom Guard is released under the MIT License.
MIT License
Copyright (c) 2025-2026 Phantom Guard Contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Phantom Guard is built on the shoulders of giants:
- Rich - Beautiful terminal output
- Typer - CLI framework built on Click
- HTTPX - Modern async HTTP client
- hugovk/top-pypi-packages - PyPI download statistics
Stay vigilant. Stay protected.
Made with care to protect the open source community.