Security scanner for Python dependencies - detects typosquats, CVEs, malicious hooks, unused deps, and metadata anomalies
Project description
PyDepSpy - Python Dependency Security Scanner
PyDepSpy is a production-ready CLI tool that scans Python project dependencies for security vulnerabilities and suspicious packages. It runs 5 independent detection engines in parallel across your dependency tree, detecting typosquats, CVEs, malicious install hooks, unused dependencies, and metadata anomalies.
Why PyDepSpy?
✅ 5 Detection Engines - Comprehensive scanning:
- Typosquat Detection: Finds packages similar to popular ones (e.g.,
requetsinstead ofrequests) - CVE Scanner: Queries OSV.dev for known vulnerabilities
- Malicious Hooks: AST-scans
setup.pyfor suspicious install-time code execution - Ghost Dependencies: Identifies unused declared dependencies (security surface area)
- Metadata Auditor: Flags red flags in PyPI metadata (no homepage, brand new packages, suspicious emails)
✅ Parallel Execution - Scans 50 packages in ~3 seconds (not 50 seconds)
✅ Local Caching - Second scan of same project is instant (24-hour TTL on API responses)
✅ Beautiful Output - Rich terminal tables with color-coded severity
✅ Multiple Formats - Terminal, JSON, and SARIF (GitHub Code Scanning)
✅ CI/CD Ready - Exit code 1 on CRITICAL/HIGH findings, composable in pipelines
Installation
pip install pydepspy
Or from source:
git clone https://github.com/tanuj437/pydepspy.git
cd pydepspy
pip install -e .
Quick Start
# Scan current project (terminal)
pydepspy scan
# Scan a specific directory (example used below)
pydepspy scan --project F:\\Vedika
# Output as JSON
pydepspy scan --format json
# Save to file
pydepspy scan --output report.json
# Use SARIF for GitHub Code Scanning
pydepspy scan --format sarif --output results.sarif
How I used it
Example: scanned F:\Vedika and produced JSON and terminal reports. Commands used:
# Run a JSON scan (PowerShell)
python -m pydepspy.cli scan --project F:\\Vedika --format json
# Run the terminal report
python -m pydepspy.cli scan --project F:\\Vedika
Sample JSON output (trimmed):
{
"version": "1.0",
"findings": [
{"package": "torch", "severity": "CRITICAL", "type": "CVE", "cve_id": "GHSA-47fc-vmwq-366v", "fix": "Upgrade to >= 1.13.1"},
{"package": "numpy", "severity": "MEDIUM", "type": "CVE", "cve_id": "GHSA-6p56-wp2h-9hxr", "fix": "Upgrade to >= 1.21"},
{"package": "huggingface_hub", "severity": "LOW", "type": "METADATA_ANOMALY"}
],
"statistics": {"total": 8, "by_severity": {"CRITICAL": 1, "HIGH": 0, "MEDIUM": 1, "LOW": 6}}
}
Actionable next steps after a scan:
- Immediately address CRITICAL/HIGH findings (upgrade or remove packages).
- Inspect UNUSED_DEP items and remove unused dependencies from your manifest.
- Pin or avoid brand-new packages until vetted.
- Re-run PyDepSpy and your test suite after changes.
These examples show the exact commands and a real scan result to make it clear how to use PyDepSpy in your workflow.
Usage
Basic Scan
$ pydepspy scan
🔍 Scanning .
✓ No issues found across 24 packages
With Findings
$ pydepspy scan
🔍 Scanning .
┏━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┓
┃ Severity ┃ Package ┃ Type ┃ Message ┃
┡━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━┩
│ CRITICAL │ requets │ TYPOSQUAT │ Possible typosquat │
│ HIGH │ django │ CVE │ CVE-2024-XXXXX │
│ MEDIUM │ unused-pkg │ UNUSED │ Never imported │
└──────────┴───────────────┴───────────────────┴────────────────────┘
3 CRITICAL • 1 HIGH • 1 MEDIUM across 24 packages
Command Line Options
Options:
--project PATH Path to Python project [default: current directory]
--format TEXT Output format: text, json, sarif [default: text]
--output FILE Write output to file instead of stdout
--cache / --no-cache Use local cache for API responses [default: cache enabled]
--help Show help message
Exit Codes
0- No CRITICAL or HIGH findings1- One or more CRITICAL or HIGH findings detected- Other - Error occurred during scanning
This makes PyDepSpy composable in CI pipelines:
pydepspy scan || exit 1 # Fail the build if issues found
Output Formats
Terminal (Default)
Beautiful, human-readable Rich tables with color-coded severity.
JSON
Structured output for programmatic processing:
{
"version": "1.0",
"findings": [
{
"package": "malicious-pkg",
"severity": "CRITICAL",
"type": "TYPOSQUAT",
"message": "Possible typosquat of: requests",
"cve_id": null,
"fix": null
}
],
"statistics": {
"total": 1,
"by_severity": {"CRITICAL": 1, "HIGH": 0, "MEDIUM": 0, "LOW": 0}
}
}
SARIF
For GitHub Code Scanning integration:
pydepspy scan --format sarif --output results.sarif
Then upload to GitHub:
gh codeql database upload-results results.sarif --repository=...
Supported Formats
PyDepSpy automatically detects and parses dependencies from:
requirements.txt- Standard pip formatpyproject.toml- PEP 621 and Poetry formatsetup.py- Setuptools install_requiresPipfile/Pipfile.lock- Pipenv format
Caching
API responses are cached locally at ~/.pydepspy/cache.db with a 24-hour TTL:
# Use cache (default)
pydepspy scan
# Disable cache
pydepspy scan --no-cache
# Clear cache
rm ~/.pydepspy/cache.db
Second scans of the same project are instant! 🚀
Development
Setup
git clone https://github.com/tanuj437/pydepspy.git
cd pydepspy
pip install -e ".[dev]"
Run Tests
pytest
pytest --cov=pydepspy
Run Linters
black pydepspy tests
ruff check pydepspy tests
mypy pydepspy
Architecture
PyDepSpy uses a modular, detector-based architecture:
- Parsers - Extract dependencies from various formats
- Detectors - Independent scanning engines that return standardized
Findingobjects - Aggregator - Deduplicates and scores findings
- Reporters - Render output in different formats
- Cache - SQLite-backed with TTL
- CLI - Click-based entry point
Each detector runs concurrently via asyncio.gather() for maximum performance.
Roadmap
v0.1.0 (Current)
- ✅ Typosquat detection
- ✅ CVE scanner
- ✅ Install hook inspector
- ✅ Ghost dependency finder
- ✅ Metadata auditor
- ✅ Terminal, JSON, SARIF output
- ✅ Caching
v0.2.0 (Planned)
-
--fixflag for auto-upgrading vulnerable packages - GitHub Actions integration (SARIF upload + CI enforcement)
- More metadata anomaly checks
- Custom rule support
- Real-time PyPI monitoring
PyPI & Library Usage
PyDepSpy is available as a CLI and as a Python library for integration in other tools.
Install from PyPI:
pip install pydepspy
Use as a CLI (console script):
pydepspy scan --project /path/to/project --format json
Or import the library in Python:
# Parsing packages
from pydepspy.parser import parse_pyproject
packages = parse_pyproject('pyproject.toml')
# Running detectors programmatically
from pydepspy.detectors import TyposquatDetector, CVEDetector
from pydepspy.aggregator import aggregate_findings
import asyncio
async def run_scan(packages):
detectors = [TyposquatDetector(), CVEDetector()]
tasks = [det.check(pkg, ver) for pkg, ver in packages for det in detectors]
results = await asyncio.gather(*tasks)
findings = [f for res in results for f in (res or [])]
return aggregate_findings([findings])
# Example usage
# aggregated = asyncio.run(run_scan(packages))
# print(aggregated)
Publishing checklist
Follow these steps to publish a new release to PyPI:
- Bump version in
pyproject.toml(already bumped to 0.1.1). - Update
CHANGELOG.mdwith notable changes. - Ensure tests and linters pass:
python -m ruff check pydepspy tests python -m black --check --target-version py39 pydepspy tests python -m pytest -q
- Build distributions:
python -m pip install --upgrade build twine python -m build
- Verify artifacts in
./dist. - Upload to TestPyPI first:
python -m twine upload --repository testpypi dist/*
- After verification, upload to PyPI:
python -m twine upload dist/*
- Tag the release and push tags:
git tag v0.1.1 git push --follow-tags
Notes:
- Use a clean venv to avoid dependency conflicts when building/publishing.
- Consider signing with GPG for authenticity.
License
MIT License - see LICENSE file
Contributing
Contributions welcome! Please:
- Fork the repo
- Create a feature branch (
git checkout -b feature/something) - Add tests
- Submit a PR
Acknowledgments
- OSV.dev - Free vulnerability database
- PyPI Simple API - Package metadata
- Rich - Beautiful terminal output
- Click - CLI framework
Contact
- 🐛 Issues: GitHub Issues
- 💬 Discussions: GitHub Discussions
- 📧 Email: tanuj.saxena.rks@gmail.com
Made with ❤️ for Python security
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pydepspy-0.1.1.tar.gz.
File metadata
- Download URL: pydepspy-0.1.1.tar.gz
- Upload date:
- Size: 29.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1ae1cc43d684210a52732a2ad16978f229b4cba6cd1ba4fc97eee5013817bc43
|
|
| MD5 |
067035ebc9d3b7a738467d40bafb9171
|
|
| BLAKE2b-256 |
e18fe720431ad19a2756443f47be5ea5b00db4a38a2551c31ad2a7db2e530d1a
|
File details
Details for the file pydepspy-0.1.1-py3-none-any.whl.
File metadata
- Download URL: pydepspy-0.1.1-py3-none-any.whl
- Upload date:
- Size: 26.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
78fd509d4b358c33c255b55e5b9dc609f09b3d25b1a25fe414548516089aca59
|
|
| MD5 |
60ab21f4f7b56696610e1324733ee24b
|
|
| BLAKE2b-256 |
1aeabfe78dd7d032eb07b0e8586a262b307e76489242b422a84298c1a72c95d1
|