In March 2026, the axios npm package — downloaded over 400 million times per month — was backdoored for three hours. Developers who ran npm install during that window silently had their credentials stolen and a remote access trojan installed.
The tools most teams use — Trivy, Snyk, Dependabot — didn’t catch it. Not because they failed. Because they weren’t designed for this.
TL;DR
- Existing scanners catch known CVEs. They miss newly published malicious packages.
- We built gate, an open-source Python CLI that adds a quarantine window, install script inspection, and maintainer change detection.
- Zero runtime dependencies — a supply chain tool that trusts its own supply chain is not a security tool.
- Available now:
pip install gate-cli
The Gap in Your Current Tooling
Vulnerability scanners work by comparing package versions against a database of known CVEs. That model has a fundamental limitation: the database has to know about the vulnerability first.
Supply chain attacks increasingly exploit this lag. A threat actor compromises a maintainer account, pushes a malicious version, and developers pull it before any scanner has seen it. The axios attack had a three-hour window. The CanisterWorm campaign spread across 47 packages before automated detection caught it.
This isn’t a scanner failure — it’s a category of attack the scanner was never built to catch.
The question isn’t “does this package have a known CVE?” — it’s “should I trust this package right now?”
What Gate Does Differently
Gate runs six checks on every package before it enters your project:
| Check | What it catches |
|---|---|
| CVE scan | Known vulnerabilities via OSV.dev |
| Quarantine window | Versions published within N days |
| Install script inspection | Suspicious postinstall hooks in npm packages |
| Maintainer change | Package ownership changed between versions |
| Hash verification | Tampered packages via lock file integrity |
| SBOM export | CycloneDX 1.6 bill of materials |
The CVE scan is table stakes — OSV.dev is free, comprehensive, and covers both PyPI and npm. The interesting checks are the rest.
The Quarantine Window
This is the core idea. A package published two hours ago has not been reviewed by the community, scanned by automated systems, or flagged by security researchers. Gate treats recency as a risk signal.
$ gate check requests
⚠ requests 2.33.0 Published 3 day(s) ago (quarantine window: 7 days)The default window is 7 days, configurable in .gate.toml. You can set it to 14 days for stricter environments, or move recent_release from warn_on to fail_on to block the install entirely.
This would have flagged the axios attack. The malicious versions were live for three hours — a 7-day window catches that with six days to spare.
Install Script Inspection
npm allows packages to run arbitrary code on installation via postinstall hooks. Legitimate packages use this for native module compilation. Malicious packages use it for everything else.
Gate checks install scripts against a pattern list:
curl, wget — network fetcheval( — code executionbase64 — encoding/obfuscationhttps?:// — hardcoded URLsx.x.x.x — hardcoded IP addressespowershell — Windows executionchild_process — Node.js process spawning$ gate check event-stream --npm
✗ event-stream 3.3.6 install script [postinstall]: node -e "..." suspicious: eval execution, hardcoded URLA clean install script passes silently. A suspicious one fails the check with the matched patterns shown.
Maintainer Change Detection
When a package changes hands — through sale, account compromise, or abandonment pickup — the new maintainer has full publish access. Gate compares the current version’s maintainers against the previous version and flags differences.
This is how attacks like event-stream (2018) work: a new maintainer takes over a popular package and pushes a malicious update. Gate makes that change visible.
Hash Verification
Gate compares the integrity hashes in your lock file against what the registry actually serves. A mismatch means the package content changed after you locked it — which shouldn’t happen.
For PyPI packages with --hash=sha256: in requirements.txt, Gate extracts those hashes automatically. For npm, it uses the integrity field in package-lock.json.
Zero Dependencies — And Why It Matters
Gate has zero runtime dependencies. No requests, no rich, no click.
This wasn’t an afterthought — it’s the entire point. A supply chain security tool that uses third-party packages is itself a supply chain attack surface. If gate depends on requests, and requests gets backdoored, your security scanner becomes the delivery mechanism.
Every check in Gate is implemented using Python’s standard library: urllib.request for HTTP calls, tomllib for TOML parsing, ANSI escape codes for terminal colors, json for everything else.
$ pip show gate-cli | grep RequiresRequires:Nothing. That’s the right answer for a tool like this.
Installation and Basic Usage
pip install gate-cliCheck a single package:
gate check lodash --npmgate check django==4.2.0Scan your whole project (auto-detects poetry.lock, Pipfile.lock, requirements.txt, or package-lock.json):
gate scanInstall as a git pre-commit hook — runs automatically when lock files change:
gate initExport a CycloneDX SBOM:
gate scan --sbom report.cdx.jsonConfiguration
Create .gate.toml in your project root to override defaults:
quarantine_days = 14
fail_on = ["critical_cve", "install_script", "recent_release"]warn_on = ["maintainer_change"]| Option | Default | Description |
|---|---|---|
quarantine_days | 7 | Days a new release must age before passing |
fail_on | ["critical_cve", "install_script"] | Exit 1 conditions |
warn_on | ["recent_release", "maintainer_change"] | Warn but allow through |
What You Can Do Today
If you want to protect your projects right now:
- Install gate —
pip install gate-cli - Run a scan on an existing project —
cd your-project && gate scan - Install the pre-commit hook —
gate init— so new installs are checked automatically - Add to CI —
gate scanexits non-zero on errors, so it integrates cleanly into any pipeline
For stricter environments, set quarantine_days = 14 and add recent_release to fail_on. For SBOM compliance requirements, gate scan --sbom report.cdx.json produces a CycloneDX 1.6 document.
What Gate Doesn’t Do
Gate is not a replacement for Trivy or Snyk — it complements them. Those tools are better at deep CVE tracking, license compliance, and container scanning. Gate adds the pre-publication risk layer they don’t cover.
Gate also doesn’t sandbox packages or do runtime analysis. It’s a static pre-install check. If a malicious package has no suspicious install script and was published more than 7 days ago, Gate won’t catch it — but your CVE scanner might.
The right answer is both.
Related Posts
- The Package You Trusted: How the Axios Supply Chain Attack Happened — The attack that motivated building gate: a deep dive into how axios was backdoored for three hours in March 2026
- GitHub Secrets Management Crisis 2026 — What happens after credentials are stolen via a supply chain attack