depsentinel 🛡️
Supply chain attack scanner for PyPI packages.
Most vulnerability scanners only check against known CVE databases — reactive by nature. depsentinel catches what they miss: malicious install hooks, obfuscated payloads, data exfiltration, CPU bombs, and dependency confusion attacks, before the package ever runs on your system.
Install
pip install depsentinel
Usage
# Drop-in replacement for pip install
depsentinel pip install requests
depsentinel pip install numpy pandas
# View scan history
depsentinel audit
How It Works
Two phases run in sequence before any package is installed:
Phase 1 — Static Analysis
Downloads the package without installing it, then inspects:
- Typosquatting — Levenshtein distance check against the top 5000 PyPI packages (
requets,djano, etc.) - Provenance — package age, download count, missing source repository
- AST scan — parses every
.pyfile in the package for:exec()/eval()with dynamic arguments at module levelbase64.b64decode→execchains (obfuscated payloads)subprocess,os.system,os.popencalls- Network calls at module level (
requests.get,socket.connect, etc.) - Reads of sensitive files (
.ssh/,.aws/credentials,.m2/settings.xml) - Environment variable harvesting (
SECRET,TOKEN,API_KEY, etc.) - High-entropy string literals (encrypted/encoded payloads)
sys.pathmutation (path poisoning)
- Metadata anomalies — compiled binaries with no source, git URLs in dependencies
Phase 2 — Dynamic Sandbox
Imports the package inside an isolated subprocess with:
- CPU time limit (10s hard cap via
RLIMIT_CPU) - Memory cap (512MB via
RLIMIT_AS) - Process limit (no fork bombs via
RLIMIT_NPROC) - Network fully blocked (socket.connect patched)
- Subprocess execution blocked
- Sensitive file reads intercepted
Reports on:
- Import time (infinite loop / CPU bomb detection)
- Background threads spawned on import (crypto miners, C2 beacons)
- Network connection attempts
- Subprocess execution attempts
- Sensitive file access attempts
- Memory growth on import (OOM bomb detection)
Output
────────────────────────────────────────────────────
Scanning: requets
→ requets v0.0.1
[STATIC]
✗ Likely typosquat of 'requests' (edit distance 1)
✗ Published 2 days ago
✗ Very low downloads: 14/month
✗ setup.py calls subprocess.run at module level
✗ base64 import + exec() = obfuscated payload pattern
🚫 Risk: CRITICAL
🚫 Install blocked: requets
────────────────────────────────────────────────────
Scanning: requests
→ requests v2.33.1
[STATIC]
✓ Risk: LOW
[DYNAMIC]
✓ Import time OK (0.509s)
✓ No unexpected threads spawned
✓ No network attempts detected
✓ No subprocess calls detected
✓ No sensitive file access detected
✓ Memory growth OK (+0MB)
✓ Risk: OK
✓ All packages passed. Proceeding with install...
Risk Levels
| Level | Action |
|---|---|
| OK / LOW | Proceeds automatically |
| MEDIUM | Proceeds with warning logged to audit |
| HIGH | Prompts for confirmation before Phase 2 |
| CRITICAL | Hard block — install does not proceed |
Audit Log
Every scan is appended to ~/.depsentinel_audit.jsonl:
depsentinel audit
# 2025-04-13T10:22:01 LOW requests
# 2025-04-13T10:23:44 CRITICAL requets
Attack Types Detected
| Attack | Static | Dynamic |
|---|---|---|
| Malicious install hooks | ✅ | ✅ |
| Obfuscated payload (base64+exec) | ✅ | ✅ |
| Credential harvesting | ✅ | ✅ |
| Network exfiltration | ✅ | ✅ |
| Typosquatting | ✅ | — |
| Dependency confusion | ✅ | — |
| CPU bomb / infinite loop | ⚠️ partial | ✅ |
| OOM bomb | ❌ | ✅ |
| Thread spawning (miner/C2) | ❌ | ✅ |
| Fork bomb | ❌ | ✅ |
| Monkey patching | ⚠️ partial | ✅ |
Limitations
- Dynamic sandbox uses
setrlimit— full isolation requires Linux (unshare --net). On macOS/Windows, network blocking is applied via socket patching only. - Transitive dependency scanning (sub-deps) is on the roadmap.
- Maven/Gradle support coming soon.
License
MIT
Metadata
Release files for depsentinel 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| depsentinel-0.1.1.tar.gz | 12.0 kB | Without provenance | Details for depsentinel-0.1.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| depsentinel-0.1.1-py3-none-any.whl | Python 3 | none | any | Details for depsentinel-0.1.1-py3-none-any.whl |
Total release size: 26.0 kB
Release files / depsentinel-0.1.1.tar.gz
| Download URL | depsentinel-0.1.1.tar.gz |
|---|---|
| Size | 12.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cbe71640a651ac66a1608976a14378ea081ee585dc4540d843f113ec16974e9f
|
|
BLAKE2b-256 checksum How to use checksums |
769cd9a6fadf1349a1487997c4c985259a3405bdd77775d18dfedd1c07189902
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / depsentinel-0.1.1-py3-none-any.whl
| Download URL | depsentinel-0.1.1-py3-none-any.whl |
|---|---|
| Size | 14.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5aed866508c3b8a720921eabea8b735b768e2f9a748f3272a1c7895fa11a5aaa
|
|
BLAKE2b-256 checksum How to use checksums |
1f61b82f60c9fc0b2cb1c10a52f42c341aa5c041f1421dd73ee9ec0ef230614c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Security for depsentinel 0.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.