Skip to content

ATOM00blue/safeinstall

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

1 Commit
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ”’ SafeInstall

Pre-flight risk check before npm install, pip install, or cargo add. Single static binary. Zero runtime dependencies. Runs offline-friendly.

CI Go Reference License: MIT

safeinstall add lodash

β†’ Score the package, prompt if risky, then run the underlying installer.


Why this exists

May 2026 has been a record month for npm supply-chain attacks:

  • Mini Shai-Hulud worm hit 314 npm packages including TanStack, OpenAI, Mistral, Grafana
  • Axios hijacked in March (100 million weekly downloads)
  • Nx Console poisoned VS Code extension breached GitHub itself (3,800 internal repos exfiltrated)
  • 454,600+ malicious npm packages catalogued in 2025; 99% on npm

npm install runs arbitrary code from the internet on your laptop. So does pip install. So does cargo add. There is no pre-flight check by default.

SafeInstall is the missing pre-flight. It scores a package against:

  • Known-malicious advisories (OSV: hard block)
  • Package age (very new = high risk)
  • Weekly downloads (very low + high churn = suspicious)
  • Maintainer count (1 maintainer = hijack risk)
  • Recent change pattern (long-quiet package suddenly republished β€” the Axios pattern)
  • Install scripts (postinstall, preinstall)
  • Typosquatting against the top popular packages
  • Known CVEs
  • Missing source repository

If the score crosses your threshold, it prompts before installing. If it's a known-malicious package, it refuses outright.


Quick start

Install

go install github.com/ATOM00blue/safeinstall/cmd/safeinstall@latest

Or download a prebuilt binary from Releases.

Use

# Drop-in replacement for the install step
safeinstall add lodash
safeinstall add axios@1.7.2

# Just check; don't install
safeinstall check requests --ecosystem pip

# Audit every direct dependency in the current project
safeinstall audit

The ecosystem is auto-detected from package.json / requirements.txt / Cargo.toml in the current directory; override with --ecosystem.


What a report looks like

$ safeinstall check loadash --ecosystem npm

SafeInstall report: loadash@1.0.0 (npm)
------------------------------------------------------------------------
SIGNAL                 POINTS   DETAIL
------------------------------------------------------------------------
package_age            0/15     Package established (3529 days old).
weekly_downloads       0/15     Widely downloaded (38595/week).
maintainer_count       10/10    Single maintainer (bus factor / hijack risk).
recent_change          0/15     No suspicious recent activity.
install_scripts        0/10     No install scripts detected.
typosquat              10/10    Name is 1 edit(s) from popular package "lodash" - possible typosquat.
vulnerabilities        0/10     No known vulnerabilities.
missing_repository     0/5      Source repository declared.
------------------------------------------------------------------------
TOTAL: 20/100  (LOW)

Commands

safeinstall add <pkg>[@version]...   Score, prompt, then install
safeinstall check <pkg>[@version]    Score only (exit 1 if >= threshold)
safeinstall audit                    Score every direct dep in this project
safeinstall config [show|init]       Show or initialize .safeinstall.json
safeinstall version                  Print version
safeinstall help                     Show usage

Common flags

-e, --ecosystem <npm|pip|cargo>     Override auto-detection
-t, --threshold <0-100>             Risk threshold (default 60)
-y, --yes                           Skip prompt; auto-install if score < threshold
-q, --quiet                         Suppress non-essential output
    --json                          Emit reports as JSON
    --no-color                      Disable ANSI colors
-c, --config <path>                 Override config file path

Exit codes

Code Meaning
0 Success: installed, or check passed
1 Risky: user declined, threshold exceeded, hard block
2 Tool error (network, parse, config)
3 Underlying installer (npm/pip/cargo) failed

Risk signals

Signal Weight Triggers when
Malicious advisory (OSV) HARD BLOCK OSV flags the package as malicious
Denylist HARD BLOCK Package is in your config denylist
Package age 15 Created < 7d (15) / < 30d (10) / < 90d (5)
Weekly downloads 15 < 100 (15) / < 1k (10) / < 10k (5)
Maintainer count 10 1 maintainer (10) / 2 (5)
Recent change 15 New version on >1yr-old package, published <7d ago (15)
Install scripts 10 preinstall / install / postinstall present
Typosquatting 10 Levenshtein distance ≀ 2 from a popular package
Known vulnerabilities 10 CVEs by max severity (critical=10, high=7, etc)
Missing repository 5 No repository or homepage URL

Allowlisted packages are capped at score 20 regardless of signals.


Configuration (.safeinstall.json)

safeinstall config init creates this in your current directory:

{
  "threshold": 60,
  "prompt": "risk",
  "allowlist": [],
  "denylist": []
}
Key Values Default
threshold 0–100 60
prompt always / never / risk risk
allowlist []string of trusted package names []
denylist []string of always-blocked packages []

Resolution order: built-in defaults β†’ ~/.safeinstall.json β†’ ./.safeinstall.json β†’ --config flag.

prompt:

  • risk (default): prompt only when score β‰₯ threshold
  • always: prompt on every install
  • never: never prompt; refuse install if score β‰₯ threshold (good for CI)

Use in CI

# .github/workflows/security.yml
- run: go install github.com/ATOM00blue/safeinstall/cmd/safeinstall@latest
- run: safeinstall audit --json --threshold 60 > audit.json

Exit code 1 if any direct dependency scores β‰₯ threshold.


How it compares

Tool What it does Open Source Pre-install gate Free
SafeInstall (this) Pre-flight scoring across npm/pip/cargo MIT Yes Yes
Socket.dev SaaS supply-chain analysis Partial Yes (paid plans) Free tier
Snyk Vuln scanning + IDE No No Freemium
OSV-Scanner CVE scanning of installed deps Yes (Apache 2.0) No (post-install) Yes
npm audit Built-in vuln scanner Yes No (post-install) Yes
Dependabot Vuln alerts on installed deps Yes No Yes

The differentiator: most tools scan after you've already installed. SafeInstall scores before the network call to the registry.


Limitations (be skeptical of any tool that doesn't list these)

  • Not a sandbox. We don't actually isolate the install β€” we just decide whether to run it.
  • Not full static analysis. We don't parse package source code.
  • Best-effort network calls. OSV/registry timeouts degrade gracefully but reduce signal accuracy.
  • The typosquat list is a curated subset. Add to internal/typosquat/*_top.go via PR.
  • PyPI install-script detection is unimplemented. PyPI doesn't expose this in metadata; needs source inspection.
  • Cargo build-script detection is unimplemented. Same reason.
  • No transitive dep checking yet. v0.1 only scores the direct package you're installing.
  • Maintainer-change detection is heuristic. npm doesn't expose maintainer history; we use "recently modified + old package" as a proxy.

Roadmap

  • v0.1: scan, check, audit, config (npm + pip + cargo)
  • v0.2: safeinstall init-hook to wrap npm/pip/cargo via shell alias
  • v0.2: GitHub Action wrapper
  • v0.3: Transitive dependency scoring
  • v0.3: Maintainer history caching for true diff
  • v0.4: Tarball inspection (suspicious file types, embedded binaries)
  • v0.4: Lockfile drift detection
  • v0.5: Custom rule plugins (YAML)

Programmatic API

import (
    "context"
    "github.com/ATOM00blue/safeinstall/internal/registry"
    "github.com/ATOM00blue/safeinstall/internal/osv"
    "github.com/ATOM00blue/safeinstall/internal/scorer"
    "github.com/ATOM00blue/safeinstall/internal/types"
)

ctx := context.Background()
info, _ := registry.New().Lookup(ctx, types.NPM, "axios", "1.7.2")
vulns, _ := osv.New().Query(ctx, types.NPM, "axios", "1.7.2")
report := scorer.Score(info, vulns, types.DefaultConfig())
fmt.Printf("score=%d level=%s\n", report.Score, report.Level)

Contributing

git clone https://github.com/ATOM00blue/safeinstall.git
cd safeinstall
go test ./...
go build -o sical ./cmd/safeinstall   # local binary; rename if Windows AV gets twitchy
./sical check lodash

We especially want:

  • Additions to the curated typosquat lists in internal/typosquat/*_top.go
  • Real-world false-positive reports
  • Detection rules for newly-disclosed campaigns (open an issue with the campaign name)

See CONTRIBUTING.md for the full guide.


License

MIT β€” use it, fork it, ship it in your enterprise toolchain.


Built in response to the May 2026 npm Mini Shai-Hulud campaign and the broader supply-chain attack wave. The package registries should do this for us. They don't. So here we are.

About

Pre-flight risk check before npm/pip/cargo install. Single static Go binary. Built in response to the May 2026 npm Mini Shai-Hulud and Axios hijack supply-chain attacks.

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages