OSS Supply Chain Scanner — paste package.json, requirements.txt, pyproject.toml
Paste a package.json, requirements.txt, or pyproject.toml and instantly check your dependencies against OSV.dev's vulnerability database. Free, browser-only, no signup. Supports npm, pip, Poetry, uv, and Rye. Built as a hub for our axios, LiteLLM, Trivy, and GlassWorm supply chain coverage.

Makoto Horikawa
Backend Engineer / AWS / Django
Paste a package.json, requirements.txt, or pyproject.toml and instantly check your dependencies against OSV.dev's vulnerability database. Free, browser-only, no signup. Supports npm, pip, Poetry, uv, and Rye. Built as a hub for our axios, LiteLLM, Trivy, and GlassWorm supply chain coverage.
Paste your dependencies, get the answer in 10 seconds. A free, browser-only scanner.
Paste a package.json, requirements.txt, or pyproject.toml, hit Scan, and the tool tells you whether any of your declared dependencies has a known vulnerability. No signup, no install, just the browser.
The motivation comes from the past six months: axios (1 billion weekly downloads) compromised, LiteLLM hijacked, Trivy triggering a cascade that took down four OSS in ten days, GlassWorm hiding malware in invisible characters. OSS supply chain attacks are now routine. I wanted a 10-second answer to "is my project actually OK?" without firing up a CLI.
Try pasting your file in the textarea below. The three sample buttons load an npm, pip, or Poetry example.
OSS Supply Chain Scanner
Data source: OSV.dev (Google, CC BY 4.0). The query runs entirely in your browser; pasted content is sent only to OSV.dev.
Quick glossary — what CVE, OSV, and "dependencies" actually mean
If you ran the scanner and the results came back full of CVE, GHSA, and OSV labels, or you are not sure what a package.json "dependency" even is, here is the one-level-down explanation for the terms in this article. Engineers with a vulnerability scanner already in CI can skip this section.
| Term | In one sentence | A level deeper |
|---|---|---|
| dependency | A piece of someone else's code your project borrows to run | A typical web app pulls in dozens to thousands of libraries. This tool inspects only the ones you borrow directly. |
| package.json | The dependency list for Node.js / npm projects | A JSON file declaring "this project uses this library at this version range". |
| requirements.txt | The dependency list for Python / pip projects | The file pip install -r requirements.txtreads to install everything at once. |
| pyproject.toml | The modern dependency list for Python (Poetry / uv / Rye) | The successor to requirements.txt, following the PEP 621 standard. Describes the whole project in one file. |
| CVE | The global tracking number for a security flaw | Common Vulnerabilities and Exposures. Format: CVE-2026-8832.Coordinated by MITRE in the US. |
| GHSA | GitHub's own security advisory ID | GitHub Security Advisory. Format: GHSA-xxxx-xxxx-xxxx.Tightly coupled to npm / PyPI; sometimes published before a CVE number is assigned. |
| OSV | A federated database of vulnerability records | Open Source Vulnerability. Hosted by Google, aggregates GitHub, PyPA, Rust Foundation, and more. This is the database the scanner queries. |
| SemVer | The global convention for version numbers | Semantic Versioning.1.2.3 = major.minor.patch.^1.2.3 means "latest 1.x". |
| supply chain attack | A library you trust gets quietly poisoned | Attacker publishes a malicious version of a library with millions of downloads. Every project that pulls the update is infected at once. |
Read end-to-end, the scanner does this: read the list of libraries your project borrows (package.json and friends), and check each one against the global wound register (OSV) keyed by the security flaw IDs (CVE / GHSA). A supply chain attack is when one of those borrowed libraries itself gets poisoned — imagine the locksmith who cut your house key being bought off.
If your team already runs npm audit or Trivy in CI, this exact lookup is happening behind the scenes on every build. This tool is just that same lookup, manually, in your browser, once.
Why browser-only?
Tools that do this already exist: npm audit, pip-audit, Trivy, Snyk, Dependabot. If you are a professional engineer, you have probably wired one of them into CI.
But the real-world friction shows up elsewhere:
- · A vendor sends you a
package.jsonand you want a sanity check before the PR review - · An OSS supply chain attack hits the news and your Slack lights up with "are we affected?"
- · You spot an interesting GitHub repo and want a dependency health check before cloning
- · You need to audit code written by a non-engineer manager or a freelance contractor
In all of these, installing a tool locally is too much friction, corporate proxies block CLIs, or you simply lack permission. Paste-and-click takes 10 seconds.
The other reason is that I wanted a landing point for the individual incident articles on this site. axios, LiteLLM, Trivy, GlassWorm, TeamPCP—each post tells the story of an attack, but until now there was no "and here is how you check yours" exit. This tool is that exit.
How it works under the hood
There is no backend. The page is HTML and JavaScript; whatever you paste is sent straight to the OSV.dev public API and the result is rendered in the browser. OSV.dev is a vulnerability database operated by Google, aggregating GitHub Security Advisory, PyPA, the Rust Foundation, and other upstream sources. It is unauthenticated, CORS-enabled, and accepts up to 1,000 packages per batch.
The pipeline is four steps:
| Step | What happens | Library used |
|---|---|---|
| (1) Format detection | Starts with { → npm. Contains [project] → Poetry/PEP 621. Otherwise requirements.txt. | Hand-rolled heuristic |
| (2) Dep extraction | JSON.parse / TOML parse / regex per line | smol-toml |
| (3) Version normalization | Resolve ^1.7.7 or >=2.0.0,<3to the lowest compatible version | semver |
| (4) Vulnerability match | POST all deps to OSV.dev/v1/querybatch in one request | fetch API |
Step (3) was the messiest. OSV.dev does not accept SemVer ranges like ^1.7.7, so we collapse a range to its lowest compatible version using semver.minVersion() and query that. It is the safer side to err on.
So "axios": "^1.7.7" is queried as 1.7.7 even if your install resolves to 1.7.9 or 1.8.2. Without lock files we cannot do better, and accepting that tradeoff is what keeps the tool useful for declaration-only files.
The match itself looks like this (the full source is in the page HTML):
// Ship every dep to OSV.dev in a single batch
const queries = deps.map(d => ({
package: { name: d.name, ecosystem: d.ecosystem }, // npm / PyPI
version: d.resolvedVersion, // normalized via semver.minVersion()
}));
const res = await fetch("https://api.osv.dev/v1/querybatch", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ queries }),
});
const { results } = await res.json();
// results[i] is the vuln list for deps[i].No backend means there is nothing for me to operate, but more importantly your package.json, even one from a proprietary internal project, never touches my servers. OSV.dev is the only third party in the loop, and they are transparent about what they store.
The fine print on each input format
package.json (npm / yarn / pnpm)
All four dependency fields are picked up: dependencies, devDependencies, optionalDependencies, peerDependencies. Excluded: workspaces (local refs), npm: aliases, and VCS specs like git+ssh://.
requirements.txt (pip / pip-tools / pipenv-lock exports)
Supports the operators ==, >=, ~=, !=. Comma-separated specs on a single line (django>=4.0,<5.0) collapse to the lowest version. Lines starting with -r, -e, or --index-url, plus # comments, are skipped.
pyproject.toml (Poetry / uv / Rye / PEP 621)
Two competing styles coexist in the wild; both are supported:
- ▸ PEP 621 standard (uv, Rye, Hatch, etc.): the array
[project].dependenciesand the table[project.optional-dependencies]. Each entry is a PEP 508 string like"requests>=2.28.0". - ▸ Poetry style: the table
[tool.poetry.dependencies]and grouped[tool.poetry.group.*.dependencies]. Values are SemVer-flavored strings ("^2.28.0") or inline tables like{ version = "...", extras = [...] }.
Parsing is done with the lightweight smol-toml library. The python entry and any inline tables with path, git, or url (local or VCS refs) are excluded from the OSV query.
What this tool does not catch
Worth listing the blind spots so the tool is not over-trusted:
- ? Transitive dependencies are invisible. Only the top-level deps you declared are scanned. A lock file (
package-lock.json,poetry.lock) would cover them, but this tool intentionally targets the small declaration files. - ? Range-only specs are scored at their lowest version. Your actually-installed version may be newer and unaffected, or older and worse off. Treat this as a coarse health check, not a 0-day verdict.
- ? Unpublished vulnerabilities won't appear. There is always a window between disclosure and OSV.dev indexing.
- ? Pure malware injection isn't detected. If a compromised package was assigned a CVE or GHSA, it shows up; if it wasn't (the first 24 hours of most supply chain attacks), nothing here will help. GlassWorm-style invisible-character malware is also out of scope.
For real coverage you need npm audit or Trivy in CI, SBOM discipline, and committed lock files. This tool is the "paste-and-glance" rung below that.
Recent OSS supply chain attacks (2025–2026)
Below is a timeline of the supply chain incidents covered on this site over the past several months. Each row links to the full write-up with the detection details and blast radius at the time.
| When | Incident | Scope | Article |
|---|---|---|---|
| 2026-05 | axios npm hijack | 1B weekly downloads RAT planted in package | axios article |
| 2026-04 | Trivy cascade | 4 OSS fell in 10 days the defender's tool itself broken | cascade / Trivy 3rd time |
| 2026-04 | Telnyx PyPI breach | Malware hidden inside a WAV file | Telnyx |
| 2025-12 | LiteLLM hijack | 95M monthly downloads Python startup = pwn | LiteLLM / .pth trace |
| 2025-10 | GlassWorm | Malware hidden in invisible Unicode chars | GlassWorm |
The technique changes every time, but the entry point is the same: "a package you trust bumps a version, and somewhere in there a stranger has rewritten the contents." Routinely glancing at the dependency file you never touch is, in effect, a defense line.
Roadmap and requests
Current scope stops at "paste three formats." Planned for the next pass:
- ▸
package-lock.jsonandpoetry.locksupport (transitive deps included) - ▸
Gemfile/Cargo.toml/go.mod - ▸ Direct GitHub URL scanning (needs an API proxy for CORS)
If something is missing for your workflow, drop a comment or use the contact form and the priority list gets reshuffled.
Sources and licensing
- • Vulnerability data: OSV.dev (operated by Google, aggregating GitHub Security Advisory, PyPA, Rust Foundation, and more, under CC BY 4.0)
- • API spec: OSV API Documentation
- • SemVer parser: node-semver (npm Inc., ISC)
- • TOML parser: smol-toml (Cynthia Rey, BSD-3-Clause)
- • ESM CDN: esm.sh
OSV.dev vulnerability metadata is redistributed under CC BY 4.0. This tool is an independent client and is not an OSV.dev or Google product.