Togoder security

npm package security report

napi-postinstall@0.3.4 security report

Risky patterns found that deserve a look.

Needs review Version 0.3.4 Files reviewed 7 Size 24.9 KB Scanned

Summary

Togoder Security scanned the npm package napi-postinstall@0.3.4 on Oct 6, 2026. An AI review of 7 source files produced 2 high, 11 medium, 6 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.

0
critical
2
high
11
medium
6
low

Findings 19

high

Shell command execution with string interpolation

NPS-1484734A4435

execSync is called with a template string that interpolates pkg, version, and constants into an npm install command. If any of these values originate from an attacker-controlled package.json (e.g. a malicious dependency name/version), command injection is possible. The same pattern appears in the yarn P'n'P branch (yarn add -D ${pkg}@${version}).

lib/index.js:105
high

Shell command execution with string interpolation

NPS-C7600FF125B5

execSync with yarn add -D ${pkg}@${version} uses interpolated values from package metadata. A crafted package name could inject shell metacharacters and execute arbitrary commands in the P'n'P environment.

lib/index.js:224
medium

Opaque downstream behavior

NPS-EA664602C314

The core logic is delegated to checkAndPreparePackage in ./index.js, which is not visible here. The safety of this CLI depends entirely on that implementation, which could contain network calls, credential harvesting, or process spawning.

lib/cli.js:24
medium

Dynamic code execution via require()

NPS-9FBB457382B9

The function uses require(packageJsonPath), require(bindingEntry), and require(pkgDir) to load modules. In the WebContainer branch, bindingEntry is constructed from values read from package.json (napi.packageName, napi.binaryName, name, version). If an attacker can influence package.json contents, this could lead to loading arbitrary code from paths derived from the package metadata.

lib/fallback.js:37
medium

File system manipulation outside package scope

NPS-3974FD1242F3

Writes to os.tmpdir() by removing and recreating a directory named after the package (${name}-${version}) and installing dependencies there. This manipulates shared temporary storage and could overwrite or interfere with other applications' temporary files if name/version collide.

lib/fallback.js:44
medium

Process spawning / shell command execution

NPS-2B3AF5968949

Uses execFileSync to execute 'pnpm' (WebContainer path) and a package-manager-derived executor (npx/pnpm/yarn/bun/deno) with constructed arguments. While using execFileSync avoids shell interpolation, it still executes external binaries and could be abused if package.json fields (name, version, napi info) are attacker-controlled, allowing arbitrary package installation or execution.

lib/fallback.js:57
medium

Command Execution

NPS-2C7A450A31D4

Uses child_process.execSync to run 'npm config get registry', which spawns a shell command. While intended to read the npm registry configuration, this executes an external command at import/runtime. If an attacker can manipulate the environment or npm binary, this could lead to arbitrary command execution.

lib/helpers.js:13
medium

Dynamic Module Resolution

NPS-3D342C2A6407

Uses require.resolve(name + '/package.json') where 'name' is a parameter. If this function is called with untrusted input, it could resolve and load arbitrary packages, potentially leading to unexpected module loading or path traversal. In this context, it's likely called with a known package name, but the pattern is risky.

lib/helpers.js:44
medium

Command Execution

NPS-9944A3D5B15F

Uses child_process.execSync to run 'ldd --version' to detect musl libc. This spawns a shell command based on the runtime environment. The command is fixed, but it still executes an external process at import/runtime, which could be exploited if the PATH or ldd binary is compromised.

lib/helpers.js:128
medium

Insecure HTTP fallback

NPS-A04AC5C70AAE

fetch uses the plain http module when the URL starts with http://. This allows package downloads over an unencrypted channel, enabling man-in-the-middle tampering with the downloaded binary package.

lib/index.js:16
medium

Untrusted URL redirect following

NPS-197F538AC24F

The fetch function follows HTTP redirects (301, 302, 307, 308) to arbitrary locations without validating the destination host. A malicious or compromised NPM registry response could redirect the download to an attacker-controlled server, leading to download of a malicious tarball that is then extracted and used.

lib/index.js:18
medium

File system writes outside package scope

NPS-51C3D309757E

The install logic writes/renames files into node_modules paths resolved from require.resolve and ancestor directories (path.resolve(pkgDir, hostPkg.split('/').map(() => '..').join('/'), pkg)), potentially modifying files outside the current package's own directory tree.

lib/index.js:137
medium

Dynamic module loading / resolution

NPS-F06EC73461BA

require.resolve is invoked on computed package names derived from package.json metadata, and require(packageNameOrPackageJson + '/package.json') uses an externally supplied string. This can trigger loading of arbitrary packages specified by a malicious manifest.

lib/index.js:174
low

Filesystem access at runtime

NPS-EC816DD39B48

The CLI reads package.json from the current working directory using fs.readFileSync. While this appears to be legitimate behavior for verifying the local package version before invoking checkAndPreparePackage, it represents filesystem access that could be abused if the downstream functions behave unexpectedly.

lib/cli.js:8
low

Top-level execution on import

NPS-A0A834FA04B4

Code executes immediately at module load time (reads process.argv and calls checkAndPreparePackage). If this module is imported rather than run as a CLI, execution still occurs, potentially triggering unintended side effects.

lib/cli.js:19
low

Environment variable manipulation

NPS-843DF9A42DDF

Sets process.env[SKIP_${name...}_FALLBACK] = '1' to bypass future fallback checks. While not inherently malicious, it modifies global process state that persists for the lifetime of the process.

lib/fallback.js:68
low

Dynamic import / module cache manipulation

NPS-68C4646230F0

Deletes the resolved package path from require.cache and re-requires it. This cache-busting technique can cause re-execution of top-level module code and may be used to force reload of modified modules.

lib/fallback.js:70
low

File System Access

NPS-0C088C3DDED2

Reads /usr/bin/ldd directly from the filesystem to detect musl. While not malicious per se, it accesses system files outside the package scope. This is a common pattern for native module detection but should be noted.

lib/helpers.js:96
low

Environment variable access

NPS-089856F0D962

The code reads process.env and spreads it into the child process environment ({ ...process.env, npm_config_global: undefined }), and reads process.env.npm_config_user_agent. Environment contents are passed to spawned npm processes, which is standard but broadens exposure of any secrets present in the environment to the child process.

lib/index.js:94

Files reviewed

FileVerdictWhat the reviewer saw
lib/cli.js medium The CLI itself shows no direct malicious code, but it performs filesystem reads and delegates core behavior to an unaudited index.js module, warranting review of the downstream implementation.
lib/fallback.js medium The code is a legitimate native-addon fallback mechanism but performs several potentially risky operations—dynamic require of computed paths, spawning package managers from metadata, and writing to shared temp directories—that could be exploited if package.json or napi metadata is attacker-controlled.
lib/helpers.js medium The code appears to be a legitimate helper module for detecting native platform targets and managing npm packages, but it uses shell command execution and dynamic module resolution that could be exploited if inputs are untrusted.
lib/index.js medium This appears to be legitimate napi binary-fetching logic, but it contains risky patterns: shell command construction via string interpolation of package metadata (command injection risk), unvalidated redirect following and HTTP fallback in downloads, and file system writes outside package scope.
lib/constants.js safe No malicious patterns detected
lib/target.js safe Cleared by Jev triage; no further analysis needed
lib/types.js safe No malicious patterns detected

Frequently asked questions

Is napi-postinstall safe to use?

No confirmed malware was found in napi-postinstall@0.3.4, but the review flagged 2 high, 11 medium, 6 low severity findings for risky patterns worth checking before you rely on it.

Does napi-postinstall contain malware?

No malware was identified in napi-postinstall@0.3.4 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 napi-postinstall checked?

Togoder Security downloaded the published npm package and had an AI model read its 7 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 napi-postinstall 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 napi-postinstall@0.3.4, cost nothing.

Related security reports