Security

TakeApart reads lockfiles, manifests, SBOMs and version files, never your application code.

What TakeApart reads

TakeApart reads lockfiles with their manifests for npm, PHP (Composer), Python (Poetry, uv and Pipenv), Ruby (Bundler) and Rust (Cargo), and CycloneDX (1.2 to 1.7) or SPDX (2.2 or 2.3) SBOMs from any ecosystem, including Maven, Gradle, Go and .NET. For the PHP, Node or Python version it also reads version files such as .nvmrc, .php-version and .python-version, the Dockerfile and GitHub Actions workflows, only for the version they set up. It doesn’t clone repositories or read application code.

How findings are ranked

TakeApart ranks findings with Score v2.1. Evidence rules place each finding in a group of the fix order and a score orders findings within it. The rules are deterministic and published here. Every analysis records the method and the date of each source it used, so anyone can run it again and get the same result.

Each finding shows its evidence state next to its severity, as a fact. Exploitation is likely when there’s a public exploit or its FIRST EPSS score is 10% or more. A CVE counts for a package version only if the record it belongs to says that version is affected, for KEV, EPSS and public exploits alike.

Being exploited right now
In CISA’s Known Exploited Vulnerabilities catalog (KEV), so it has been exploited in the wild.
A public exploit exists
Metasploit has a module for it or nuclei has a detection template for it.
Likely to be exploited
Its FIRST EPSS score, the estimated probability that it’s exploited in the next 30 days, is 10% or more.
No known exploit
An EPSS score under 10%, and none of the above.
No exploitation data
No EPSS score, because there’s no CVE or FIRST hasn’t scored it, and none of the above. Missing data is never counted as zero.

A package is in the group of its highest finding. The fix order lists the upgrades that take packages out of Fix first, then those in Fix next, then Low risk. The fix list numbers that order, and each package’s card gives the reason in one line.

Fix first
Exploited, in any dependency. Or exploitation likely in a package that ships, when the vulnerability is automatable (over the network, with no privileges or user interaction) or has total impact (confidentiality, integrity and availability all high, or code execution).
Fix next
Exploitation likely in a development dependency, or in a package that ships when the vulnerability is neither automatable nor total impact. A critical or high severity with no exploitation evidence. A critical rating with no CVE, so no EPSS score.
Low risk
Everything else, collapsed at the bottom of the fix order.

The groups are modeled on CISA’s Stakeholder-Specific Vulnerability Categorization (SSVC). Fix first corresponds to Act, Fix next to Attend and Low risk to Track. Where SSVC weighs mission impact, TakeApart uses whether a package ships with the app or is only a development dependency.

Code execution means the vulnerability’s own title or description says it allows code or command execution. Automatable and total impact come from the CVSS vector. Without a vector, only code execution can count.

Within a group, findings are ordered by a score from 0 to 100 that weighs exploitation (KEV and EPSS) 40%, severity (CVSS) 30%, exposure (the CVSS attack vector) 15% and blast radius (how much of the app depends on the package) 15%. When a finding has no EPSS score and isn’t in KEV, its severity stands in for exploitation, capped at the value of an EPSS score of 10%, so a finding with no CVE is ordered by its severity but never above the likely line. Missing data never counts as zero. The score only sets the order. It never moves a finding to another group.

A package a malware advisory names (a GitHub malware advisory or an OSV malicious-package record) isn’t ranked. It’s listed above Fix first as a malicious package to remove, and no version of it is offered as a fix.

A vulnerability GitHub hasn’t reviewed (published by NVD, with a package and affected versions) shows on its package as unconfirmed, below the confirmed findings. It isn’t ranked, counted in any group or put in a prompt. Once GitHub reviews it, it’s a finding like any other.

CISA’s KEV catalog, Metasploit Framework module metadata (Rapid7, BSD-3-Clause) and the nuclei-templates CVE list (ProjectDiscovery, MIT) are mirrored every six hours, keeping only CVE ids. A mirror more than three days older than the rest of the data, or one that couldn’t be fetched, isn’t used. Evidence then falls back to the sources that are available, and the finding says so. Exploit-DB isn’t used.

Score v2.1 (20 Oct 2026) keeps v2’s rules and groups and changes only the order within a group: the capped severity stand-in above. Score v2 (19 Oct 2026) introduced the evidence rules.

Sources Metasploit Framework (BSD-3-Clause) and nuclei-templates (MIT).

What an import sends

An uploaded file is read in the browser. Only package names (the project’s own included), versions, ecosystems, which packages are development dependencies, which are private or not checked and how the packages connect are sent to TakeApart’s server, with the PHP, Node or Python version the files pin or allow and the kind of file it came from (such as Dockerfile or composer.json).

Package names and versions are looked up in OSV (run by Google), the names of packages with known vulnerabilities in their ecosystem’s public registry (the npm registry, Maven Central, PyPI, Packagist, RubyGems, crates.io, NuGet or the Go module proxy) to check which versions are published (and, where no version fixes a package, its latest release and the day it was published), and the vulnerability ids found in FIRST’s EPSS service. The CISA KEV catalog and the Metasploit and nuclei-templates exploit lists are downloaded whole every six hours. The project’s own name is never looked up or stored. Private packages, from a registry other than the public one, are marked in the browser and never sent to any lookup; they show as “Private, not checked”. Packages that don’t come from a registry (local paths, VCS and other URLs, editable installs, requirements includes that aren’t followed, go.mod local replaces) are never looked up either and show as “Not checked” with the reason. pnpm and Yarn berry lockfiles don’t record a private registry set only in .npmrc or .yarnrc.yml, so those packages are looked up by name.

For the PHP, Node and Python versions an import pins or allows, TakeApart’s server reads public data every six hours and stores it in the database: OSV’s Bitnami vulnerability records, php-src’s published vulnerability reports on GitHub, the Node.js security team’s vulnerability list, CVE.org for each runtime CVE’s CVSS score, FIRST’s EPSS scores and endoflife.date’s release and end-of-life dates. Each is read whole, so none of them receives anything about an import. A runtime version is matched against the stored data on TakeApart’s server and never sent anywhere.

Every 10 minutes TakeApart’s server reads GitHub’s advisory database (reviewed, unreviewed and malware entries), with repository paste’s read-only token, and OSV’s lists of recently changed vulnerability records for each supported ecosystem. It asks only for what changed since its last run, so neither GitHub nor OSV receives anything about an import, an app or a visitor. When an advisory names a package, the cached lookups for that package are dropped and the next import asks OSV again. The database keeps each advisory’s id, source and times for 90 days, and the unreviewed and malware entries that name packages, which imports are matched against on TakeApart’s server.

What it keeps

Nothing that identifies an import. The result is shown in the browser and isn’t saved; reloading the page clears it. Public vulnerability lookups (OSV, FIRST EPSS and npm release data) are cached per package version and shared, so repeat lookups are faster. OSV is asked again for each package after an hour. Other cached lookups are used for at most a day, except a vulnerability record, which is kept until OSV reports a newer version of it. The cache doesn’t record who asked. Every six hours the database stores the CVE ids from the CISA KEV catalog and the Metasploit and nuclei exploit lists, replacing the previous copy.

To rate limit imports, repository pastes, new explanations and upgrade impact lookups, a keyed hash (HMAC) of the IP address is recorded with the time, never the address itself.

Usage counts

TakeApart counts usage as daily totals of named actions, such as an import finished (by source and kind of file, never the file’s name) or a card opened, and ranges of time spent on the model and on the list. No IP address, identifier, cookie or package, project or repository name is recorded with the counts. Nothing is stored on the visitor’s device for this. Counts are split by phone or desktop, from the window’s width in the browser. The width itself, the browser and the user agent aren’t recorded.

Retention

  • Rate-limit records (a keyed IP hash and the time) are deleted after 24 hours.
  • Cached public vulnerability lookups are deleted within three days.
  • Event counts are daily totals with no identifier and are kept with no end date.
  • Explanations are deleted after 60 days.
  • Records of new and changed public vulnerability data, and the unreviewed and malware entries kept for matching, are deleted after 90 days.

Scheduled database jobs do the deleting, every hour for the 24-hour rules and once a day for the others.

Repository paste

A pasted repository is read by TakeApart’s server through GitHub’s or GitLab’s public API. It reads only the root lockfile and manifest, a pinned requirements file, go.mod, gradle.lockfile or an SBOM on the default branch, clones nothing and stores nothing. For the runtime’s version it also reads a version file (such as .nvmrc or .php-version), the Dockerfile and up to five GitHub Actions workflows. To find them it reads the repository’s details (visibility and default branch), the list of files at the root, when there’s a requirements directory its file list and its base.txt or prod.txt, and when there’s a .github directory the list of workflows. GitHub is read with a token that reads public repositories only, and GitLab without a token. Beyond that it fetches nothing from the repository. What goes to the vulnerability services is the same as for an upload. Vercel’s request logs keep the result’s /r/ address and the outgoing API requests for a day. Explanations for its findings work as for any import. The result’s link reads the repository again when it’s opened, and search engines are asked not to index it.

Upgrade impact

Upgrade impact works out what a fix involves from dependency data alone: the smallest version that takes a package out of Fix first, the release lines it crosses, the packages that must move with it and why, and the manifest edits. TakeApart’s server reads release data from Packagist and the npm registry by public package name, cached per package for up to two days and shared, never per application. The lockfile’s and manifest’s version ranges are sent only when Impact opens and aren’t stored. No code is read and no LLM is involved. Private packages are never looked up.

What the LLM sees

Opening a fix-now or plan finding on an import shows a short explanation written by Anthropic’s model. The model is given public vulnerability data and the package’s name and version, nothing else. It never learns which application the package belongs to and never sees source code, secrets or anything else a visitor sends. Each explanation is cached per vulnerability and package version and shared across visitors, under a monthly spending limit. It never changes a score, a tier or the fix order. The Juice Shop demo’s explanations were written ahead of time with Juice Shop’s dependency paths and scores, since it’s a public app.

Subprocessors

NamePurposeWhat it receivesRegion
VercelHosts the site and runs the analysis.Request logs, including IP addresses, the pages requested (such as a repository result’s /r/ address) and outgoing API requests, kept for a day on TakeApart’s plan. (Vercel’s runtime logs documentation)Seoul (icn1), with pages and static files served from Vercel’s network
AnthropicWrites the explanations for findings on imports, and wrote the Juice Shop demo’s ahead of time.Public vulnerability data and package names and versions. Never which application, and nothing else a visitor sends.USA
SupabaseThe database for rate limiting, the event counter and the vulnerability-lookup cache.Keyed IP hashes (HMAC) with a time, daily event counts, public vulnerability data, public package release data, explanations and their monthly spend and hourly API call counts per repository host.Seoul (ap-northeast-2)
GitHubRepository paste: the files at a public repository’s root, read through GitHub’s API.The repository’s name and requests for its manifest, lockfile and SBOM files, from TakeApart’s server with a token that reads public repositories only. Nothing about the visitor.USA
GitLabRepository paste: the files at a public repository’s root, read through GitLab’s API.The repository’s name and requests for its manifest, lockfile and SBOM files, from TakeApart’s server without a token. Nothing about the visitor.USA
PackagistUpgrade impact for Composer packages: their releases and what each requires.Public package names, from TakeApart’s server. Nothing about the application or the visitor.Not published (hosted by Private Packagist, served through Bunny.net’s CDN)