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:

CheckWhat it catches
CVE scanKnown vulnerabilities via OSV.dev
Quarantine windowVersions published within N days
Install script inspectionSuspicious postinstall hooks in npm packages
Maintainer changePackage ownership changed between versions
Hash verificationTampered packages via lock file integrity
SBOM exportCycloneDX 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.

Terminal window
$ 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 fetch
eval( — code execution
base64 — encoding/obfuscation
https?:// — hardcoded URLs
x.x.x.x — hardcoded IP addresses
powershell — Windows execution
child_process — Node.js process spawning
Terminal window
$ gate check event-stream --npm
event-stream 3.3.6
install script [postinstall]: node -e "..."
suspicious: eval execution, hardcoded URL

A 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.

Terminal window
$ pip show gate-cli | grep Requires
Requires:

Nothing. That’s the right answer for a tool like this.


Installation and Basic Usage

Terminal window
pip install gate-cli

Check a single package:

Terminal window
gate check lodash --npm
gate check django==4.2.0

Scan your whole project (auto-detects poetry.lock, Pipfile.lock, requirements.txt, or package-lock.json):

Terminal window
gate scan

Install as a git pre-commit hook — runs automatically when lock files change:

Terminal window
gate init

Export a CycloneDX SBOM:

Terminal window
gate scan --sbom report.cdx.json

Configuration

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"]
OptionDefaultDescription
quarantine_days7Days 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:

  1. Install gatepip install gate-cli
  2. Run a scan on an existing project — cd your-project && gate scan
  3. Install the pre-commit hookgate init — so new installs are checked automatically
  4. Add to CIgate scan exits 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.



Sources