Skip to main content

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 .py file in the package for:
    • exec()/eval() with dynamic arguments at module level
    • base64.b64decodeexec chains (obfuscated payloads)
    • subprocess, os.system, os.popen calls
    • 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.path mutation (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

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)

Source distribution for depsentinel 0.1.1
File Size Uploaded
depsentinel-0.1.1.tar.gz 12.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for depsentinel 0.1.1
File Interpreter ABI Platform
depsentinel-0.1.1-py3-none-any.whl Python 3 none any Details

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

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page