
Exposure management should start at the registry pull, not after packages are already installed in a build.
A malicious release reaches builds in hours, but remediation takes weeks; the chalk/debug attack hit 70 teams in ~2 hours.
Chainguard Libraries gates ingestion: source-built packages, malware scanning, and cooldowns block bad artifacts before entry.
Most exposure management programs draw the security boundary in the wrong place. They begin tracking open source dependencies only after those packages have been pulled into a build or installed in an environment, assuming they arrived clean. For open source libraries, exposure begins earlier, at the registry pull.
Treating the registry pull as part of your exposure boundary allows you to intervene earlier. And that timing is critical: a malicious release can reach automated builds within hours, while remediation programs are calibrated in weeks. Scanning can shorten how long it takes to notice the gap, but you need to control what enters the environment to shorten how long it takes to close it.
Registry takedowns don’t solve downstream exposure
On September 8, 2025, attackers compromised an npm maintainer’s publishing account through phishing and distributed malicious versions of 18 familiar JavaScript packages, including chalk and debug.
The debug maintainer’s incident advisory describes the compromised version as functionally identical to the previous patch release, except for an added cryptocurrency-interception payload. The npm-published version did not correspond to a release in the project’s source repository. So, a routine dependency update could bring the payload into an application without breaking the build or presenting a corresponding source change for review.
These compromised releases were available for roughly two hours before they were detected and removed from npm. The payload executed only when an affected package was bundled into a website and run in a browser, but Vercel still identified builds containing the compromised versions across 76 projects belonging to 70 teams. Removing the releases from npm did not remove copies already present in private registries, package caches, installed dependencies, or browser bundles.
The malicious releases needed only hours to enter automated builds, but the cleanup took much longer. It took five more days for the debug maintainer to publish a clean patch version to help users move past cached copies and rebuild. Each downstream organization also had to locate and remove its own copies.
This chalk/debug payload executed in browser environments, often after an affected package was bundled into a web application. Other compromised packages can execute during installation or Python startup, leaving little or no time to intervene once the package crosses the ingestion boundary. Recent incidents show several ways this can happen:
Incident | How the malicious release reached the registry | When the payload executed |
Malicious versions of trusted npm packages were published through compromised maintainer accounts. | Post-install scripts ran during installation, stole secrets, and supported self-replication. GitHub reported removing more than 500 compromised packages. | |
Two malicious releases were uploaded directly to PyPI, bypassing the project’s normal release cycle. | A malicious
file executed automatically on Python startup and harvested developer secrets, cloud credentials, and Kubernetes configuration. | |
New npm releases were cut after an attacker pushed malicious commits to the maintainer’s source repository. | A preinstall hook ran automatically where lifecycle scripts were permitted, before the application imported the package. |
Every CTEM stage starts after the pull
Exposure management exists to identify, prioritize, validate, and reduce your attack surface. But when a program’s scope begins with deployed assets or installed packages, dependency origin remains background information rather than an enforced condition of entry. As a result, a registry compromise may not become visible until its packages are already inside your environment.
Consider how the five stages of continuous threat exposure management (CTEM) are usually applied to installed dependencies:
Scoping establishes the application's business context for dependencies that are already installed.
Discovery inventories the packages and exposures that have already resolved into builds and environments.
Prioritization ranks findings based on risk, but only for artifacts already present.
Validation determines whether an exposure is exploitable in code that is already running.
Mobilization coordinates the work required to remediate exposure that has already arrived.
In an implementation scoped this way, each stage evaluates a dependency after it has already been pulled, leaving the registry admission decision outside your exposure management program’s scope.
Instead, you should extend the scope of your CTEM program to include the package request itself. Alongside the application’s dependency inventory, record which repository served each artifact, what source and build evidence it carries, and which admission policy allowed it through. Platform teams can then enforce the boundary at the repository level while your security teams measure those decisions as part of the exposure program.
Move the gate upstream with Chainguard Libraries
Once the package request is part of your exposure management scope, the next step is to enforce policy at that point. Chainguard Libraries puts that model into practice by replacing direct access to public registries with a controlled repository that evaluates dependencies before engineers install them.
At this gate, Chainguard Libraries handles two kinds of exposure with two different mechanisms. Malicious packages are removed: they never enter the environment. Known CVEs are fixed: the vulnerable version stays in your graph, but the artifact you run carries the fix and is recorded as fixed.
Block malicious packages before they enter your environment
By default, Chainguard Libraries serves packages that Chainguard has built from source. For these packages, the Chainguard Factory starts from attributable upstream source and builds the artifact in controlled infrastructure. Source-to-artifact integrity validation prevents a familiar package name or maintainer account from being treated as sufficient evidence that a registry upload is trustworthy. A malicious release that exists only on the registry has no source to build from, so it never shows up as a finding on your dashboard: it never entered the environment.
The LiteLLM incident mentioned earlier demonstrates how that control works. Chainguard reported that the compromised releases lacked a publicly verifiable source, so it did not build them. As a result, Chainguard Libraries for Python customers did not receive the malicious releases.
However, building from source does not address every attack path. Malware scanning will flag behaviors such as secret exfiltration and staged payloads, then block packages identified as malicious. Configurable cooldowns also withhold newly published releases. This gives detection systems and the security community time to identify an attack before the package becomes available. To expand catalog coverage, Chainguard also provides an optional protected upstream fallback that serves packages or versions that Chainguard has not built, but only after they pass the configured cooldown period and malware scan.
In the keyv/cacheable attack campaign, the attacker compromised the source repository itself, so verifying that an artifact matched its source would not have been enough. Scanning and cooldowns caught the campaign before the affected packages became available to customers.
Together, the LiteLLM incident and the keyv/cacheable incident demonstrate the importance of a layered model: source builds exclude malicious code inserted only at the registry, while scanning and cooldowns provide protection when malicious code reaches the source repository.
Use the registry pull to shorten CVE remediation time
Keeping malicious artifacts out is only one benefit of moving the scope of your exposure management further upstream. The same control point can also change how teams respond when a legitimate dependency contains a known vulnerability.
For supported packages and versions, Chainguard backports critical and high-severity fixes from newer upstream releases into the version your team is already pinned to. It runs the upstream test suite before and after applying each patch and adds regression tests to validate the fix. Teams can therefore adopt a targeted remediated build while planning a broader upgrade.
Django and Flask illustrate how this works:
Package | Upstream remediation | Chainguard backport |
Django 4.2.16 | Django 4.2.17 fixed , an Oracle-specific SQL-injection vulnerability. | applies the fix while retaining the 4.2.16 base release. |
Flask 2.0.2 | Flask 2.2.5 and 2.3.2 fixed , which could expose cached responses or session cookies under specific proxy and session conditions. | applies the fix while retaining the 2.0.2 base release. |
Every Chainguard-built package, including a remediated build, carries signatures, a signed Software Bill of Materials (SBOM), and SLSA Level 3 provenance connecting it to its source and build process.
Chainguard also publishes VEX advisories that record the remediated artifact as fixed to supported scanners. Supported versions of Grype and Trivy can recognize that status with the appropriate configuration. However, teams should validate the installed artifact rather than a dependency declaration that names only the original base version.
The impact this has on remediation time is tangible: in February 2026, Chainguard Factory remediated CVEs in an average of two days, with only 22% requiring direct human intervention.
Scanning alone can't produce that result. It shortens the time it takes to detect a malicious or vulnerable dependency, but not the time it takes to fix one, because the fix still waits on an upstream release, an upgrade, and a deploy. Controlling ingestion is what moves mean time to remediate: a malicious package that is never admitted needs no remediation, and a vulnerable one can be fixed in the version you already run.
Measure how much of your dependency graph is built from verified-source
Moving the gate upstream only reduces exposure for dependencies that actually pass through that gate. To make this control part of your exposure management program, you need to measure how much of your dependency intake is built from verified source before it enters the environment.
The core question is simple: What percentage of your distinct dependency artifacts are built from verified source?
Registry logs provide a practical starting point. Choose an application or group of builds and a reporting period, such as the previous 30 days. Export its successful package downloads, including transitive dependencies. Remove metadata requests, retries, and blocked downloads, since those artifacts did not enter the environment.
Count each distinct artifact once using its digest, or unique file fingerprint. (Package names and versions are not precise enough because identically labeled files can contain different code or come from different builds.) Then compare the observed artifacts against your build and provenance records. If an artifact lacks evidence that it was built from verified source, keep it in the total but not the verified count.
Then use the following equation to get a quantitative answer:
Observed verified-source coverage = distinct observed artifacts with verified build evidence ÷ all distinct observed dependency artifacts × 100
As an example, suppose your logs contain 1,000 distinct artifacts. Of those, 650 have verified build evidence, 200 came through protected upstream fallback without that evidence, and 150 have unverified origins. Your observed verified-source coverage is 65 percent. The fallback packages may have received malware scanning and cooldown protection, but they were not built from verified source and therefore do not belong in the verified count.
Call the result an approximation. Registry logs only show the downloads they observe. Direct downloads and local caches may bypass the repository, while some downloaded packages may never reach a final build. We recommend comparing the logs with resolved lockfiles and build SBOMs to identify those blind spots.
Use this baseline to decide which ingestion gap to close next. Continue measuring MTTR for vulnerabilities that require remediation, and track blocked packages separately. Together, those measures can show you how quickly your organization removes dangerous dependencies as well as how consistently it prevents them from entering in the first place.
Related articles