Summary
Togoder Security scanned the npm package pacote@21.5.1 on Oct 6, 2026. An AI review of 15 source files produced 4 medium, 9 low severity findings. The overall verdict is medium: the findings flag risky but common patterns (dynamic code, unsafe defaults, broad file or network access) rather than confirmed malware.
Findings 13
Lifecycle script execution
NPS-A157949C21A0
The #prepareDir method invokes runScript with event 'prepare' on the resolved directory, executing the package's prepare script during tarball creation. This is expected npm behavior for git dependencies and directory fetchers, but represents a code execution surface when handling untrusted packages. The behavior is gated by opts.ignoreScripts.
Environment variable harvesting
NPS-39A9726AD31D
The code reads process.env and spreads it into child process environment for npm commands in #prepareDir. While it filters to avoid infinite recursion via _PACOTE_NO_PREPARE_, it passes all environment variables (including potentially sensitive tokens) to npm subprocesses running install scripts.
Spawning processes or shell commands
NPS-659C8C1F8AB7
The code spawns git and npm commands via @npmcli/git and util/npm.js. This is expected for a git fetcher, but running npm install in cloned repositories means arbitrary prepare/postinstall scripts from the git dependency will execute with the user's environment.
Arbitrary code execution via dependency scripts
NPS-08550EF224A0
The #prepareDir method runs 'npm install' (via this.npmInstallCmd) in cloned git repos when scripts like postinstall, build, preinstall, install, prepack, or prepare are present. This causes arbitrary code from the git dependency to execute on the local system during install.
Environment variable injection into child process
NPS-A37912F7E5A0
The runScript call passes a custom env object including npm_package_resolved, npm_package_integrity, and npm_package_json. While these are standard npm metadata variables, injecting them into the script execution environment could be leveraged if the prepare script is untrusted.
Arbitrary file inclusion in tarball
NPS-6A619DEB4BE1
The tarballFromResolved method uses packlist to determine files and tar.c to create a tarball from the resolved directory. packlist respects npm ignore rules, but combined with the prepare script execution, this can package arbitrary files produced by the prepare script (e.g., secrets written into the directory).
Dynamic process execution
NPS-1586427D332F
Uses child process spawning through the npm() utility and git.clone() to execute git and npm binaries. Inputs like this.spec.fetchSpec are derived from package specifiers, which could be attacker-controlled in dependency chains.
network access and credential handling
NPS-32B28A244453
The file is a registry fetcher that makes HTTP requests to npm registries using npm-registry-fetch. It reads credentials/options from this.opts, which may include auth tokens or registry keys. This is expected for a package manager fetcher but means the module handles sensitive registry authentication material. No exfiltration or credential harvesting outside normal registry operations is observed.
dynamic code execution
NPS-1298F536BCC9
No eval, new Function, child_process, or dynamic code execution is present. Fetch URLs are constructed from registry configuration and package names, not from arbitrary user-controlled code. Signature verification uses crypto.createVerify and sigstore.verify, which are cryptographic verification APIs, not execution primitives.
attestation/signature verification paths
NPS-B9A7C5849C10
The manifest method fetches attestations from a URL derived from the registry and dist.attestations.url. It parses DSSE envelopes, verifies subjects against package PURLs and integrity digests, and calls sigstore.verify. While complex, this is security-relevant verification logic rather than a backdoor. No shell invocation or credential exfiltration is evident.
no install-time execution
NPS-7C6EF92D2394
This module only defines a class and exports it. There are no top-level side effects beyond requiring dependencies. No npm lifecycle scripts, process spawning, file system manipulation outside package scope, or dynamic imports are present.
Network Request
NPS-808F3124B771
The code makes network requests using npm-registry-fetch to fetch tarballs from remote registries, which is expected behavior for a package fetcher.
Header Construction
NPS-644E70CE1986
Custom headers are added to requests, including user-agent and pacote-specific headers, but these are standard for npm package operations and do not contain sensitive data.
Files reviewed
| File | Verdict | What the reviewer saw |
|---|---|---|
| lib/dir.js | medium | This file is a legitimate npm directory fetcher implementation that executes prepare lifecycle scripts and packages directory contents; no overt malicious patterns are present, but the prepare script execution and environment variable injection warrant caution with untrusted packages. |
| lib/git.js | medium | This is standard npm git fetcher code from pacote with expected git/npm subprocess execution and environment inheritance, but running install scripts from cloned git dependencies poses inherent supply-chain risk. |
| lib/registry.js | medium | No malicious patterns detected; the code is a standard npm registry fetcher with signature and attestation verification logic. |
| bin/index.js | safe | No malicious patterns detected; this is the legitimate npm CLI front-end for the pacote package handler with no data exfiltration, credential harvesting, obfuscation, or suspicious process/network activity. |
| lib/fetcher.js | safe | This is a legitimate npm package fetcher base class from the @npmcli/pacote library with no malicious patterns detected. |
| lib/file.js | safe | The FileFetcher class handles local file package extraction and executable bin chmod operations without any malicious patterns such as data exfiltration, credential harvesting, obfuscated code, or suspicious process spawning. |
| lib/index.js | safe | No malicious patterns detected; the file only re-exports fetcher classes and wraps fetch methods without any suspicious code, network requests, or dynamic execution. |
| lib/remote.js | safe | No malicious patterns detected; the code appears to be a legitimate npm package fetcher that performs expected network operations without exfiltration, credential harvesting, or other security risks. |
| lib/util/add-git-sha.js | safe | Cleared by Jev triage; no further analysis needed |
| lib/util/cache-dir.js | safe | No malicious patterns detected |
| lib/util/is-package-bin.js | safe | Cleared by Jev triage; no further analysis needed |
| lib/util/npm.js | safe | No malicious patterns detected; the file is a legitimate utility wrapper for spawning npm commands. |
| lib/util/protected.js | safe | Cleared by Jev triage; no further analysis needed |
| lib/util/tar-create-options.js | safe | Cleared by Jev triage; no further analysis needed |
| lib/util/trailing-slashes.js | safe | Cleared by Jev triage; no further analysis needed |
Scanned versions of pacote
| Version | Verdict | Files | Scanned |
|---|---|---|---|
| 21.5.1 | Needs review | 15 | Oct 6, 2026 |
Frequently asked questions
Is pacote safe to use?
No confirmed malware was found in pacote@21.5.1, but the review flagged 4 medium, 9 low severity findings for risky patterns worth checking before you rely on it.
Does pacote contain malware?
No malware was identified in pacote@21.5.1 when Togoder Security scanned it on Oct 6, 2026. A new version can still introduce malicious code, so scan the exact versions in your lockfile.
How was pacote checked?
Togoder Security downloaded the published npm package and had an AI model read its 15 source files, looking for install scripts, credential access, network exfiltration, obfuscation, backdoors and crypto-wallet theft. The results are cached by file hash and shown here.
How do I scan pacote together with the rest of my dependencies?
Upload your lockfile at https://security.togoder.click/scan or call the API documented at https://security.togoder.click/api-docs. Files that have already been scanned, like the ones in pacote@21.5.1, cost nothing.