Summary
Togoder Security scanned the npm package node-gyp@13.1.0 on Oct 6, 2026. An AI review of 20 source files produced 6 medium, 24 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 30
PATH manipulation and symlink creation
NPS-F4090C96F3FD
The code creates a symlink to the Python executable specified in config.variables.python inside build/node_gyp_bins and prepends that directory to the PATH environment variable. This could be abused if an attacker can control the 'python' value in config.gypi to point to a malicious executable, causing it to be resolved instead of the intended Python. While this is part of normal node-gyp behavior, it represents a potential attack vector for local privilege escalation or code execution during builds.
Spawning processes and shell commands
NPS-654C42041352
The code spawns external build tools (make, msbuild) via gyp.spawn using values derived from environment variables (MAKE, JOBS, and config.variables.msbuild_path). This is expected behavior for a build tool, but it means the module will execute arbitrary binaries specified through these environment variables or config files. If an attacker can influence these values (e.g., via a malicious config.gypi in the build directory), they can cause arbitrary code execution.
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.
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).
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.
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.
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.
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.
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.
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.
Execution of external build commands based on configuration
NPS-347FEEA2F123
The code reads config.gypi and uses values like msbuild_path and python directly to construct command lines that are executed. There is no validation or sanitization of these paths, which could lead to arbitrary command execution if a malicious config.gypi is present in the build directory (e.g., from a compromised dependency).
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
Environment variable harvesting
NPS-94CB92F48FBF
The parseArgv method reads all environment variables matching /^npm_config_/i and /^npm_package_config_node_gyp_/i and injects them into this.opts. While this is documented npm/node-gyp behavior, it means any npm_config_* env var (which can contain tokens, registry auth, proxies, cafile paths, etc.) is automatically absorbed into the options object and passed downstream to configure/install/build commands.
Dynamic module loading with computed input
NPS-5A5F6E694444
In the constructor, commands are built as () => require('./' + command)(this, argv), where command derives from a fixed internal array. This is not user-controlled, so risk is low, but it is dynamic require-by-name pattern worth noting.
Child process spawning
NPS-887CE2DC8765
The spawn() method uses childProcess.spawn to execute a command with args and options. Command and args come from downstream gyp build/install logic (e.g. invoking python, make, MSBuild). This is expected for node-gyp but represents arbitrary process execution surface if untrusted options (e.g. python, make, tarball, dist-url from env vars) flow through.
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.
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.
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.
Files reviewed
| File | Verdict | What 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 is standard node-gyp build logic that spawns external build tools and manipulates PATH, with potential risks if configuration files or environment variables are attacker-controlled, but no direct malicious patterns were found. |
| 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 | This is the legitimate upstream node-gyp entry module; no malicious exfiltration, backdoors, or obfuscation detected, though it inherits sensitive npm_config_* environment variables and spawns child processes by design. |
| 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. |
| commitlint.config.mjs | safe | Cleared by Jev triage; no further analysis needed |
| eslint.config.js | safe | No malicious patterns detected |
| gyp/commitlint.config.js | safe | Cleared by Jev triage; no further analysis needed |
| lib/clean.js | safe | No malicious patterns detected |
| lib/create-config-gypi.js | safe | No malicious patterns detected; the code is a legitimate node-gyp utility for generating config.gypi files without any exfiltration, credential harvesting, obfuscation, or suspicious behavior. |
| 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 | No malicious patterns detected; the file only orchestrates gyp build tasks via provided interfaces. |
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.
| Versions | Verdict | Count | Range | Top 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
Frequently asked questions
Is node-gyp safe to use?
No confirmed malware was found in node-gyp@13.1.0, but the review flagged 6 medium, 24 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@13.1.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 20 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@13.1.0, cost nothing.