Quarantine for your dependencies.

Lazaret provides static security analysis for Python, JavaScript, TypeScript and SQL, plus supply-chain and credential checks for Go and Rust. It also inspects packages from npm, PyPI, Go and Rust, editor extensions, and every install before it runs—flagging hidden payloads, leaked secrets, injection bugs and known-vulnerable versions.

pip install lazaret

Python 3.10 or later. Nothing else gets installed.

The project scanner is on npm too, with no dependencies: npx lazaret check . (Node 22 or later). The Python package includes both the scanner and MCP server; npm provides the scanner and commit-time hook but no MCP server in 0.1.10. You do not need both packages. Full MCP capability from either package is planned for 0.2.0.

A lazaret was the harbor station where arriving ships and cargo were held and inspected before they could enter port. Ships in quarantine flew a yellow flag.

$ lazaret-registry scan …
Four releases from the September 2026 benchmark, scanned from their archives. The two held were published to attack their installers (from a leading open dataset of malicious packages) and are gone from the registries.
PackageVerdictFinding
npm:chalk@6.0.1OK
npm:react-zutils@1.0.1SUSPICIOUSSC-INSTALL-HOOK its install hook starts a script that contacts an ngrok address, hidden in strings it XOR-decodes as it runs
pypi:requests@2.34.2OK
pypi:requesxs@1.0.0SUSPICIOUSSC-EVAL-DECODE runs a payload it decodes SC-TYPOSQUAT one letter from “requests”

In plain English

If you run technology rather than write code, this part is for you.

Your software is mostly other people's software

Almost every application your teams build is assembled from hundreds of free, shared building blocks, called packages, that are downloaded automatically from public warehouses such as npm (for JavaScript) and PyPI (for Python). It is a restaurant kitchen that orders its ingredients from thousands of suppliers it has never met.

Attackers poison the ingredients

Criminals publish packages named one typo away from popular ones, or break into a real publisher's account and slip a booby trap into an update. When a developer's laptop or your build server downloads it, the trap runs there, with that person's passwords and access, usually before anyone has looked at it.

Lazaret is the inspection dock

Before a package is installed, Lazaret opens it and reads what its code would do. Would it send out passwords? Run hidden code? Delete files? Then it gives a verdict, and the install tool it sits in front of (npm, pip, go, cargo and others) stops on the bad ones, as the harbor did with a ship.

  • OKNothing unusual found.
  • WARNSomething unusual that a person should know about. The install goes ahead.
  • SUSPICIOUSIt behaves like an attack. The install is held.
  • INCOMPLETEPart of it could not be read, so it is not waved through.

It reads; it never runs

Nothing in a package is installed or executed during inspection. Lazaret reads the files in memory, so inspecting a booby-trapped package cannot set the trap off.

What your team does

Put lazaret guard in front of the install command developers already use, for example lazaret guard npm install express. Run a scan in your build pipeline. Add the commit hook if you want to catch a leaked password before it is saved. It is free and open source, needs no account, and has no dependencies of its own.

Questions leaders ask

We already run a vulnerability scanner. Isn't that this?

Not quite. Tools such as npm audit, Dependabot and pip-audit compare your packages with lists of problems that someone has already found and published. A package that was poisoned this morning is on no list yet. Lazaret reads the package itself to see what it does, and it also does the list check, so you get both.

Will it block our developers for no reason?

That is the cost we watch most closely. Before every release we run it over the latest versions of 1,703 of the most downloaded packages, and none may be held. Version 0.1.9 holds none of them. Version 0.1.8 held nine by mistake, among them vite and vitest, and that was fixed. What it still warns about, and why.

How much does it catch?

On the canonical audit draw from an open dataset, it holds 454 of 516 selected malicious releases (88.0%), or 454 of the 513 that contain files to scan (88.5%). Counting releases flagged for review, it finds 478 of 516 selected (92.6%), or 478 of 513 scanned (93.2%). On 750 others that no detector was written from, the figures are 82% and 89%. No scanner catches everything: three selected releases in the canonical draw are empty, and some attacks fetch their payload after install, from outside the package. Treat Lazaret as one layer of defense, not the only one.

Does it send our code anywhere?

Scanning your code happens on your own machine. It contacts the public registries to download the packages you ask it to inspect. One feature talks to outside services, and only when you ask for it: --verify-secrets checks whether a leaked key is still live by asking the service that issued it, and says which providers it will ask before it does.

What it checks

Your code
Rules for Python, JavaScript, TypeScript and SQL, with taint tracking that follows untrusted input across functions and files into SQL, shell and template sinks, and Flask, Django, FastAPI and Express routes modeled. Go and Rust source is checked for credentials, token formats, Trojan Source characters, and hidden or encoded content. Reports as HTML, JSON, or SARIF for code scanning, with a quality gate for CI.
lazaret .
Your installed dependencies
Follows each install hook in node_modules and site-packages to the scripts it runs, and tests every file for what no library needs to do: sending credentials out, running what it downloads or decodes, starting itself at login, deleting the user's files. Vendored Go and Rust trees are read too.
lazaret . --deps
Published packages
Downloads npm, PyPI, Go module and crate archives, and VS Code extensions, scans them in memory without unpacking anything to disk, and gives each version a verdict. Reads what runs at install, at import and when the package is used, the strings it decodes as it runs, a value one file receives and another runs, who built a release and from which repository, and names one typo away from a popular package's.
lazaret-registry scan npm:left-pad
Installs, before they run
Put lazaret guard in front of npm, pnpm, yarn, Bun, pip, uv, go, cargo or your editor's extension installer: it resolves what would be installed, scans every package in memory, and installs nothing if one is suspicious, can't be checked, or is less than two days old.
lazaret guard npm install express
Secrets, and whether they are live
Finds credentials in code and config files, and, only when asked, checks with the issuing service whether a leaked key still works. The commit-time gate stops a credential, or an install hook that pipes a download into a shell, before it is committed.
lazaret hook
Known vulnerabilities
Matches the npm, PyPI, Go and Rust packages installed or pinned in a project, from eight lockfile formats including uv.lock, pylock.toml and bun.lock, against a CVE bundle built from OSV, CISA KEV and EPSS, and fails the build on versions with known-exploited vulnerabilities.
lazaret-sca . --bundle cve-bundle.json
Code your AI assistant writes
The Python package's MCP server lets Claude and other assistants scan a snippet before writing it to disk, or check the files they just changed. pip install lazaret supplies both this server and the project scanner; an npm installation is not also required. Installing only the npm package does not supply MCP in 0.1.10. Instruction files that tell an agent what to run are read for what they ask.
lazaret-mcp

Measured on real malware

Lazaret 0.1.9 and 0.1.8 were run on the same canonical audit draw, read statically: nothing was installed or run. Other tools' earlier measurements are labelled separately.

What was measuredLazaret 0.1.9Comparison
Malicious npm and PyPI releases held at the strictest verdict (516 selected; 513 scannable and three empty releases counted as misses)88.0% selected
88.5% scanned
0.1.8: 87.0% selected, 87.5% scanned
GuardDog: 71% (September, on an earlier sample)
Malicious releases held or flagged for review (the same canonical draw)92.6% selected
93.2% scanned
0.1.8: 91.1% selected, 91.6% scanned
GuardDog: 77% (September, on an earlier sample)
Other malicious releases that no detector was written from, held (750)82.4%0.1.8: 81.9%
Other tools: not run
Popular releases held by mistake (1,703 of the most downloaded npm and PyPI packages and Rust crates)00.1.8: 9
GuardDog: 18 of September's 429
Malicious npm releases blocked at install, end to end (300) †247Popular npm packages blocked by mistake: none of 219
Planted fake credentials found (99, of 33 types) †95%Gitleaks 94%, detect-secrets 91%, TruffleHog 73%
Expected advisories matched in eight lockfile formats (1,278) †100%pip-audit and npm audit each miss one

† Last measured on October 10, on an earlier build of 0.1.9, and not repeated for the release.

The canonical draw selected 516 releases. Three contain no files—bolym 1.0, detectron2 0.6 and requestsx 0.1.2—so 513 artifacts were scanned and the empty releases count as misses in the selected denominator. Lazaret 0.1.8 and 0.1.9 scanned the same 513 IDs; eleven verdicts moved upward and none moved downward. The 750-release holdout was not read while detectors were written. GuardDog's figures are from September's earlier sample, and much of the dataset was found by GuardDog's own rules, which favors it. How it was measured, and the limits, are in the README.

New in 0.1.9

Everything that changed

Nothing to trust but the standard library

A supply-chain tool with dependencies is itself a supply-chain risk. Lazaret has none. It runs on Python's standard library alone, builds without downloading anything, and its whole test suite runs on a stock interpreter. The npm package has no dependencies either, and the native engine is written with no external crates: even its regular-expression engine is its own, CPython's ported to Rust, with shortcuts that skip only work that can't match. So is its HTTPS client.

Releases are built reproducibly and published from CI with signed attestations, so any file on PyPI or npm can be traced to the exact commit and workflow that produced it. This page loads no scripts, fonts, or anything else from third parties, and its content security policy holds it to that.