Togoder security

npm package security report

node-gyp@12.4.0 security report

Risky patterns found that deserve a look.

Needs review Version 12.4.0 Files reviewed 18 Size 94.4 KB Scanned

Summary

Togoder Security scanned the npm package node-gyp@12.4.0 on Oct 6, 2026. An AI review of 18 source files produced 5 medium, 27 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
0
high
5
medium
27
low

Findings 32

medium

Suspicious symlink creation with external input

NPS-584998FB514B

Creates a symlink named 'python3' in a build directory pointing to the Python interpreter path read from config.gypi. The python path is taken from config.variables.python without validation. If an attacker controls config.gypi (e.g., via a malicious package or repo), they could symlink to an arbitrary executable, which is then prepended to PATH and executed during the build. This is a potential vector for code execution during build.

lib/build.js:170
medium

process_spawning

NPS-C5D163AC5423

The code spawns a child process using gyp.spawn(python, argv) to run gyp (a build tool). This is expected behavior for node-gyp, but it does execute an external process with arguments derived from configuration. No obvious injection vector is present, but spawning processes is a notable capability.

lib/configure.js
medium

Process spawning / command execution

NPS-E0471654E994

The code uses execFile (via ./util) to spawn processes ('py.exe', 'python3', 'python', or paths derived from environment variables). On Windows, it runs commands through a shell with shell: true, which could allow command injection if environment variables are attacker-controlled (e.g., NODE_GYP_FORCE_PYTHON or PYTHON containing shell metacharacters).

lib/find-python.js
medium

Command execution with PowerShell

NPS-1C323642C54E

The code spawns PowerShell via execFile to query Visual Studio installations. While this is expected for node-gyp's VS detection, it uses '-ExecutionPolicy Unrestricted' and dynamically constructs command strings with interpolated values from environment variables (vcInstallDir, SystemRoot). The filterArg built from VCINSTALLDIR is inserted into a PowerShell command string without escaping, which could allow command injection if VCINSTALLDIR is attacker-controlled.

lib/find-visualstudio.js:245
medium

Path traversal risk

NPS-863D19068E7C

The version string from command-line arguments (argv[0] or gyp.opts.target) is used in path.resolve(gyp.devDir, version) before being validated. If semver.parse fails (returns null), the raw version string is used directly. While path.resolve normalizes the path, a version like '../../important-dir' would resolve outside gyp.devDir. However, the subsequent fs.stat check would need to succeed before the rm is executed, and rm is restricted to versionPath. This still constitutes a file system manipulation concern where an attacker-controlled version argument could target directories outside the intended node-gyp development directory for deletion.

lib/remove.js:27
low

Home directory access

NPS-15508FC9EF40

Uses os.homedir() to resolve '~' in --devdir and to compute cache paths via env-paths. This is normal behavior for a build tool but does access the user's home directory.

bin/node-gyp.js:20
low

Process working directory modification

NPS-9042EA6EAE8E

process.chdir(dir) is called based on user-provided -C/--directory flag. This changes the CWD for the process which can affect subsequent file operations, but is a documented CLI behavior and validated as a directory first.

bin/node-gyp.js:62
low

Dynamic command dispatch

NPS-533B0005AE51

prog.commands[command.name] dynamically selects and invokes a command handler based on user-supplied argument (command.name from program args). If command.name is attacker-influenced and 'commands' contains unexpected keys, this could be leveraged for unexpected invocation - though in this context it's the intended CLI dispatch mechanism, not obfuscation.

bin/node-gyp.js:85
low

Environment variable harvesting

NPS-9515A5EDD9A2

The errorMessage() function reads and logs npm_package_name and npm_package_version environment variables. While limited to npm package metadata and only on error paths, this is a minor information disclosure pattern that could be expanded in other code paths, and it demonstrates environment variable access behavior.

bin/node-gyp.js:121
low

Spawning processes with user-controlled input

NPS-26882B016A59

The build function spawns make or msbuild with argv that may include user-supplied options (gyp.opts.make, gyp.opts.jobs, gyp.opts.solution). While this is typical for a build tool, it allows arbitrary command execution if an attacker can influence these options, e.g., through package.json or environment variables. This is expected behavior for node-gyp but should be noted as a risk in a third-party package context.

lib/build.js:199
low

environment_variable_modification

NPS-F189173A9F92

The code modifies process.env.PYTHONPATH and process.env.PYTHON, which could affect subsequent subprocesses. This is part of normal node-gyp operation but is a side effect that could potentially be abused in a compromised environment.

lib/configure.js
low

file_system_access

NPS-97EA9E421F3C

The code reads files from the node prefix directory (node_version.h) and resolves paths based on user-provided --nodedir, expanding ~ to the home directory. This is expected for node-gyp but allows reading files outside the package scope if a malicious --nodedir is provided.

lib/configure.js
low

dynamic_path_resolution

NPS-9168E8A765DA

The code constructs paths using user-controlled input (gyp.opts.nodedir, argv) and resolves them. While not directly malicious, it could be used to access unintended locations if an attacker controls the build arguments.

lib/configure.js
low

Dynamic code execution

NPS-0B99758DA292

The code uses JSON.parse on strings read from files and process.config. This is not eval or Function constructor, so it is safe, but it does parse potentially attacker-controlled config.gypi files. However, JSON.parse itself is not dangerous unless combined with eval. The parsed config is then written to a file in the build directory, which is expected behavior for node-gyp.

lib/create-config-gypi.js:18
low

File system manipulation

NPS-A0C02D4FEB16

The code reads from a path derived from nodeDir and writes to buildDir. Both are expected parameters for node-gyp. No traversal outside intended directories is evident, but nodeDir could be user-controlled via --nodedir flag, potentially allowing reading arbitrary config.gypi files. This is by design for node-gyp to support custom Node.js headers.

lib/create-config-gypi.js:27
low

Environment variable and credential harvesting

NPS-FF8A2F9908FA

The code accesses process.config and process.arch, but does not read environment variables or credential files like .npmrc, .ssh, etc. The gyp.opts object may contain user-provided command-line options, but these are not exfiltrated.

lib/create-config-gypi.js:45
low

Network request with configurable proxy and CA

NPS-F0D023D25A60

The module downloads content from a user-supplied URL using undici fetch. Proxy and CA settings are taken from gyp options or environment variables, which is normal for node-gyp-style tooling. No data is sent to unexpected external servers; requests target the provided URL.

lib/download.js:6
low

Environment variable usage

NPS-6E72DD774629

Reads http_proxy, HTTP_PROXY, https_proxy, HTTPS_PROXY to configure proxy support. This is expected behavior for a downloader and does not harvest credentials or secrets.

lib/download.js:55
low

File system read

NPS-31695B56DDF3

readCAFile reads a CA certificate file from a path provided via gyp.opts.cafile. This is explicit user configuration, not harvesting of sensitive files like ~/.ssh or cloud credentials.

lib/download.js:91
low

Environment variable harvesting

NPS-F1E18DD4E73E

The code reads numerous environment variables (USERNAME, USER, LOCALAPPDATA, SystemDrive, ProgramW6432, ProgramFiles, ProgramFiles(x86), NODE_GYP_FORCE_PYTHON, PYTHON) to construct paths and locate Python executables. While this is expected behavior for a Python finder, it could be abused to gather system/user information if the package were malicious.

lib/find-python.js
low

File system path manipulation

NPS-795582AE76A2

The code constructs absolute file paths to Python executables across Program Files and LocalAppData directories and attempts to execute them. If an attacker can place a malicious python.exe in one of these locations, it could lead to arbitrary code execution.

lib/find-python.js
low

Environment variable harvesting

NPS-4B2C0CDF52B2

Reads numerous environment variables including VCINSTALLDIR, VSCMD_VER, WindowsSDKVersion, and SystemRoot. These are used for VS detection logic, not exfiltration, but the pattern of environment variable access is present.

lib/find-visualstudio.js:68
low

Process spawning

NPS-BA9A175C4546

Uses execFile to spawn powershell.exe with -NoProfile and various commands including Get-VSSetupInstance and Add-Type for loading a local C# file. This is standard node-gyp functionality for locating Visual Studio, but represents a shell/process execution surface.

lib/find-visualstudio.js:210
low

Network download with checksum verification

NPS-A24EED0A20E0

Downloads Node.js development tarballs and Windows node.lib files from release.tarballUrl and related URLs, but verifies content against SHASUMS256.txt checksums. This is expected functionality for node-gyp's install command.

lib/install.js
low

File system manipulation outside package scope

NPS-9A3CA057BB07

Creates and manages directories under gyp.devDir (typically ~/.node-gyp) and os.tmpdir(). Files are extracted from tarballs, with only .h and .gypi files filtered in. This is standard node-gyp behavior for installing dev headers.

lib/install.js
low

Temp directory cleanup

NPS-D4921B82D3E4

Uses fs.rm with recursive:true on a temp directory created via mkdtemp, which is properly scoped and cleaned up in a finally block. Not a concern.

lib/install.js
low

Environment variable harvesting

NPS-AD5C8C66B803

The code reads environment variables matching npm_config_* and npm_package_config_node_gyp_* and injects them into options. This is legitimate for node-gyp but could expose secrets if present in environment. However, it only reads and uses them locally, not exfiltrating.

lib/node-gyp.js
low

Spawning child processes

NPS-06AB73076226

The spawn method uses childProcess.spawn to execute arbitrary commands. This is expected for node-gyp's build functionality, but could be abused if command/args are attacker-controlled. The code is part of a build tool, so this is intentional behavior.

lib/node-gyp.js
low

Dynamic module loading

NPS-6EB72FD04A2E

The constructor dynamically requires command modules based on a fixed list ('./' + command). The commands are from a hardcoded array, so no user input is used for module paths. This is safe.

lib/node-gyp.js
low

Spawning processes or shell commands

NPS-AA125525466C

The execFile function wraps child_process.execFile, which spawns external processes. While this is a legitimate utility used to run reg.exe for Windows registry queries, spawning processes is a red flag that warrants scrutiny.

lib/util.js:7
low

Environment variable usage

NPS-0FAE1019A303

regGetValue reads process.env.SystemRoot to construct the path to reg.exe. This is a standard use for locating the Windows directory and is not credential harvesting, but environment variable access is noted.

lib/util.js:14
low

File system access

NPS-873C9439218D

findAccessibleSync uses openSync to read files resolved from caller-provided candidates. This is a general-purpose file readability helper and does not target sensitive paths itself, but could be misused by callers.

lib/util.js:63

Files reviewed

FileVerdictWhat the reviewer saw
bin/node-gyp.js medium The file is the legitimate node-gyp CLI entrypoint; it contains expected CLI dispatch, logging, and directory handling behaviors with no malicious exfiltration, obfuscation, or credential theft patterns.
lib/build.js medium The code appears to be a legitimate node-gyp build script with no clear malicious intent, but it creates symlinks based on unvalidated config values and spawns build commands with user-influenced arguments, posing moderate risks if the configuration is attacker-controlled.
lib/configure.js medium The code appears to be a legitimate node-gyp configure script with expected process spawning and environment modifications, but no clear malicious patterns such as data exfiltration, credential harvesting, or obfuscated code were detected.
lib/find-python.js medium This code appears to be a legitimate Python finder utility (part of node-gyp), but it spawns processes and reads many environment variables, presenting low-to-medium risk if the package or environment is compromised.
lib/find-visualstudio.js medium This appears to be legitimate node-gyp Visual Studio detection code, but it contains a potential PowerShell command injection risk via unescaped VCINSTALLDIR interpolation and spawns PowerShell with ExecutionPolicy Unrestricted.
lib/node-gyp.js medium The code is a legitimate part of node-gyp with expected build tool functionality; no malicious patterns detected, but it does read environment variables and spawn child processes as part of its normal operation.
lib/remove.js medium The remove function may allow deletion of directories outside the intended node-gyp development directory if a malicious version string containing path traversal sequences is supplied.
lib/util.js medium The code is a legitimate utility module for spawning processes and reading files, with no evidence of malicious intent, though it does contain process-spawning and file-access primitives that warrant monitoring.
eslint.config.js safe No malicious patterns detected
lib/clean.js safe No malicious patterns detected
lib/create-config-gypi.js safe The code appears to be a legitimate part of node-gyp for generating config.gypi files, with no malicious patterns such as data exfiltration, credential harvesting, or backdoor installation detected.
lib/download.js safe The code is a legitimate download helper using undici with proxy/CA configuration and contains no malicious patterns.
lib/find-node-directory.js safe Cleared by Jev triage; no further analysis needed
lib/install.js safe This is the legitimate node-gyp install.js module which downloads Node.js development files with SHA-256 checksum verification; no malicious patterns detected.
lib/list.js safe No malicious patterns detected; the code only reads and lists directory contents within the node-gyp development directory.
lib/log.js safe No malicious patterns detected
lib/process-release.js safe No malicious patterns detected; the code is a legitimate Node.js release URL resolver from node-gyp with no exfiltration, credential harvesting, obfuscation, or suspicious execution.
lib/rebuild.js safe The file is a straightforward node-gyp rebuild helper with no obfuscation, network, filesystem, or process-spawning code; it only queues clean/configure/build tasks.

Affected version ranges

None of the 2 scanned versions of node-gyp are flagged high or critical. The latest scanned version, 13.1.0, is medium risk. Only versions we have scanned are listed; unscanned versions between them are not covered.

8.4.113.1.0
VersionsVerdictCountRangeTop findings
12.4.0 – 13.1.0 Needs review 2 >=12.4.0 <=13.1.0 process_spawning; Process spawning / command execution
8.4.1 – 12.2.0 Not scanned 2 >=8.4.1 <=12.2.0

Full list, including published versions not scanned yet: version ranges API.

Scanned versions of node-gyp

VersionVerdictFilesScanned
13.1.0 Needs review 20 Oct 6, 2026
12.4.0 Needs review 18 Oct 6, 2026

Frequently asked questions

Is node-gyp safe to use?

No confirmed malware was found in node-gyp@12.4.0, but the review flagged 5 medium, 27 low severity findings for risky patterns worth checking before you rely on it.

Does node-gyp contain malware?

No malware was identified in node-gyp@12.4.0 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 node-gyp checked?

Togoder Security downloaded the published npm package and had an AI model read its 18 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 node-gyp 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 node-gyp@12.4.0, cost nothing.

Related security reports