Skip to main content

Supply chain attack defense for pip, npm, cargo, go, gem, and Docker

Project description

safe-install

PyPI version Python 3.9+ License: MIT Zero Dependencies

Supply chain attack defense for pip, npm, cargo, go, gem, and Docker.

Zero dependencies. Every time you run pip install or npm install, any package in the dependency tree can execute arbitrary code and steal your SSH keys, cloud credentials, API tokens, browser passwords, crypto wallets, and shell history. This tool stops that.

Install

pip install safe-install

Or download standalone (zero deps)

curl -sSL https://raw.githubusercontent.com/safe-install/safe-install/main/install.sh | bash

The Problem

pip install litellm          # stole SSH keys, AWS/GCP/Azure creds, env vars
npm install event-stream     # backdoor targeting Bitcoin wallet Copay
npm install ua-parser-js     # cryptominer + password stealer (7M weekly downloads)
cargo install rustdecimal    # typosquat that stole env vars via build.rs
gem install strong_password  # backdoor via compromised maintainer account
docker pull ngnix            # typosquat cryptominer image

A single pip install some-tool can pull in hundreds of transitive dependencies, any of which could be compromised. You have no visibility into what runs during install.

Defense Layers

Layer Method Strength What it stops
1 Docker Sandbox Flawless Package code runs in isolated container with zero access to host filesystem, credentials, or network
2 Binary-only mode Flawless (install-time) Wheels/prebuilt packages don't execute code during install. Refuses source distributions.
3 Hash lockfile Flawless (tampering) SHA256 verification detects any modification to packages
4 Typosquat detection ~95% Catches name confusion attacks (e.g. reqeusts vs requests) using edit distance + popularity DB
5 Package intelligence ~90% Cross-references PyPI/npm metadata: age, maintainer history, download counts, known-malicious lists
6 Credential vault ~95% Moves sensitive files to temp vault, clears env vars during install
7 Source inspection ~70% Scans setup.py/postinstall.js/build.rs for exfiltration patterns
8 Filesystem snapshot ~85% Takes before/after snapshot of key directories, alerts on unexpected file changes
9 Vault hardening ~90% Encrypts vault contents, decoy files, tamper detection on vault directory
10 DNS defense ~80% Monitors/blocks DNS exfiltration attempts during install (encoded data in DNS queries)
11 Import guard ~75% Runtime import hook that intercepts suspicious module loads after install
12 Runtime monitor ~60% Detects unexpected outbound connections, file access, and process spawning at runtime

Use Layer 1 (Docker). Everything else is a fallback.

Distribution Channels

Channel Target Install
PyPI CLI users pip install safe-install
System tray app Desktop users pip install safe-install[tray]
VS Code extension VS Code users Install from VS Code Marketplace
Docker Desktop extension Docker users Install from Docker Hub
GitHub Action CI/CD pipelines uses: safe-install/safe-install-action@v1

Quick Start

# Check what's exposed on your machine right now
safe-install check-env

# Install a package with full protection
safe-install install requests

# Audit a package without installing
safe-install audit litellm

# Scan a local project for suspicious patterns (all languages)
safe-install scan ./my-project/

Usage

Protected Install

# Auto-detects ecosystem from package name
safe-install install requests                    # pip
safe-install install lodash                      # npm (if starts with @)
safe-install install -e npm express              # explicit ecosystem
safe-install install -e cargo serde
safe-install install -e go github.com/gin-gonic/gin
safe-install install -e docker nginx:latest

# Docker sandbox (default if Docker is available)
safe-install install flask

# Binary-only (refuse source distributions — no setup.py runs)
safe-install install flask --binary-only

# Fallback to credential vault (when Docker unavailable)
safe-install install flask --no-sandbox

# Dry run (audit everything, install nothing)
safe-install install flask --dry-run

# Force install despite critical findings
safe-install install flask --force

Audit

# Check a package before you install it
safe-install audit requests
safe-install audit -e npm lodash
safe-install audit -e cargo serde

# Scan local code for exfiltration patterns
safe-install scan ./my-project/
safe-install scan ./my-project/ --languages python,javascript

Environment Check

# See exactly what a malicious package could steal from your machine
safe-install check-env

Output:

  Sensitive files on disk:
    EXPOSED ~/.ssh (12KB)
    EXPOSED ~/.aws (1KB)
    EXPOSED ~/.gitconfig (0KB)
    EXPOSED ~/.docker/config.json (0KB)
    EXPOSED ~/Chrome/Login Data (40KB)

  Sensitive env vars set:
    EXPOSED GITHUB_TOKEN=ghp_...1234
    EXPOSED AWS_ACCESS_KEY_ID=AKIA...5678

  Isolation capabilities:
    Docker: available
    Bubblewrap: NOT available

  Summary: 5 files, 2 env vars exposed
  Any malicious package install could read ALL of these.

Configuration

Create ~/.config/safe-install/config.toml (global) or ./safe-install.toml (per-project):

[sandbox]
enabled = true
memory_limit = "2g"
cpu_limit = "2"
timeout = 600

[vault]
# Add your own sensitive paths beyond the defaults
extra_paths = [
    "~/.custom-secrets",
    "~/.my-app/credentials.json",
]
extra_env_vars = [
    "MY_SECRET_API_KEY",
    "INTERNAL_DB_PASSWORD",
]

[network]
# Additional hosts to allow during install
allowed_hosts = [
    "my-private-registry.com",
    "artifactory.mycompany.com",
]

[scan]
skip_tests = true
max_findings_display = 15

How the Docker Sandbox Works

Your machine                          Docker container
+------------------+                  +------------------+
| ~/.ssh/          |                  | (empty)          |
| ~/.aws/          |  -- INVISIBLE -> | No home dir      |
| ~/.gitconfig     |                  | No env vars      |
| $GITHUB_TOKEN    |                  | No volume mounts |
| Chrome passwords |                  | --cap-drop=ALL   |
+------------------+                  | --read-only      |
                                      | --memory=2g      |
        pip install pkg               | --no-new-priv    |
              |                       +------------------+
              v                              |
     Download + build in container           |
              |                              |
     Copy .whl files out <-------------------+
              |
     pip install --no-deps *.whl  (just unzips, no code runs)

The malicious code runs inside the container where there is literally nothing to steal. The wheels that come out are just zip files — installing them doesn't execute any code.

What Each Ecosystem Defends Against

Ecosystem Attack vector How safe-install stops it
pip setup.py runs during install Sandbox builds wheels; local install is just unzip
npm preinstall/postinstall scripts --ignore-scripts + sandbox download
cargo build.rs runs at compile time Sandbox compilation; scan for suspicious build scripts
go init() functions run on import Sandbox build; scan for network calls in init
gem extconf.rb runs during install Sandbox build; scan for command execution
docker Malicious Dockerfiles/images Scan Dockerfiles for pipe-to-shell, privileged mode

Limitations

  1. Import-time attacks: The sandbox protects install-time. A malicious __init__.py still runs when you import the_package in your real environment. Defense: virtual environments + runtime monitoring.

  2. Obfuscated code: The source inspector uses pattern matching. Sophisticated obfuscation (encrypted payloads, steganography, multi-stage loaders) can evade it. Defense: the Docker sandbox doesn't care about obfuscation — there's nothing to steal.

  3. Without Docker: Falls back to credential vault, which is good but not perfect. An attacker who knows about safe-install could look for the vault temp directory, or access paths not in the sensitive list. Defense: install Docker.

  4. Compiled extensions: Native C/C++ extensions in wheels can contain anything. The source inspector can't analyze compiled code. Defense: audit compiled packages separately, prefer pure-Python alternatives.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

safe_install-0.1.0.tar.gz (65.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

safe_install-0.1.0-py3-none-any.whl (74.7 kB view details)

Uploaded Python 3

File details

Details for the file safe_install-0.1.0.tar.gz.

File metadata

  • Download URL: safe_install-0.1.0.tar.gz
  • Upload date:
  • Size: 65.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for safe_install-0.1.0.tar.gz
Algorithm Hash digest
SHA256 b72bf1f8b6ee445ba33b8c295839ce8a17730b29d04e21903b070c9aebff4b2c
MD5 9fcf4bf1e2339149e6915c0976edac17
BLAKE2b-256 3f1ac10a6df7a1ec61b210fb285954b59099d8504ba8ddd84f06c2c84b0493dd

See more details on using hashes here.

File details

Details for the file safe_install-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: safe_install-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 74.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for safe_install-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4d615fce39ccdac0b4807024c711ec3fa9b3ef64a1712ecda813a6127a114fa9
MD5 72cb639b9bcdaee64a0fa5f0d536a875
BLAKE2b-256 adfba59c6e85d3a40d93ebcf5c8353fff08df0d4dcd993fc7062903602290b94

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page