Togoder security

npm package security report

@semantic-release/npm@13.1.5 security report

Risky patterns found that deserve a look.

Needs review Version 13.1.5 Files reviewed 16 Size 19.7 KB Scanned

Summary

Togoder Security scanned the npm package @semantic-release/npm@13.1.5 on Oct 6, 2026. An AI review of 16 source files produced 5 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.

0
critical
0
high
5
medium
9
low

Findings 14

medium

Project-scoped config file read

NPS-BF6EDA062BC0

Falls back to reading '<cwd>/.npmrc'. In untrusted working directories this could pick up an attacker-controlled .npmrc if the caller later uses the resolved registry URL to fetch or publish packages. The function itself only returns a registry URL string and does not perform network I/O. Risk depends on callers, not this file.

lib/get-registry.js:7
medium

Spawning processes or shell commands

NPS-D9A5E4C0C821

The code uses execa to spawn 'npm' processes (npm version and npm pack) with user-influenced arguments (npmrc, pkgRoot, tarballDir, cwd, env). While this is expected for a semantic-release plugin, the npmrc path and pkgRoot/tarballDir values are passed directly to the child process without validation, which could potentially allow path traversal or injection if these inputs are attacker-controlled. The tarballDestination path is resolved using path.resolve with tarballDir.trim(), which could allow moving files outside the intended directory if tarballDir contains '../' sequences.

lib/prepare.js:15
medium

File system manipulation outside package scope

NPS-6F11C1CABAA8

The move operation uses path.resolve(cwd, tarballDir.trim(), tarball) as the destination. If tarballDir contains path traversal sequences (e.g., '../../etc'), the tarball could be moved outside the project directory. This is a potential directory traversal issue.

lib/prepare.js:45
medium

External dependency trust boundary

NPS-790BD1E0148F

The security of this module depends entirely on the imported exchangeToken implementation from ./token-exchange.js. If that module sends the OIDC token or context credentials to an attacker-controlled endpoint, this function would silently enable it. The import is static, not dynamic, but it is the primary risk vector.

lib/trusted-publishing/oidc-context.js:2
medium

Credential exchange / token handling

NPS-5A12055E85CB

The function conditionally calls exchangeToken(pkg, context) only when the registry matches OFFICIAL_REGISTRY. This is a trusted-publishing OIDC flow that exchanges an identity token for a registry token. While the logic itself appears legitimate for npm trusted publishing, the exchangeToken dependency is not shown and could be malicious. The result is coerced to a boolean and returned, so no direct exfiltration is visible in this file.

lib/trusted-publishing/oidc-context.js:5
low

Environment variable harvesting

NPS-3770E91F2137

Reads NPM_CONFIG_REGISTRY and NPM_CONFIG_USERCONFIG environment variables. These are legitimate npm-published env vars and are not sensitive credentials on their own, but any code reading env vars in a package deserves a mention for review context. No secrets such as AWS/SSH/PyPI credentials are read.

lib/get-registry.js:6
low

Credential/config file access

NPS-C2D36D662E56

Reads npm configuration via rc('npm', ...) and explicitly targets env.NPM_CONFIG_USERCONFIG or path.resolve(cwd, '.npmrc'). This is standard behavior for resolving the npm registry (used by npm client itself), but the code does touch a credential-adjacent configuration file (~/.npmrc / project .npmrc), which can contain auth tokens. No exfiltration occurs; the file content is only fed to registry-auth-token's registry-url resolver.

lib/get-registry.js:7
low

Environment variable and credential harvesting

NPS-15C7C9F122CF

The code passes the 'env' object directly to the spawned npm processes and uses 'npmrc' as a userconfig path. If the npmrc path is controlled by an attacker, it could point to a malicious configuration that exfiltrates credentials or executes arbitrary scripts. However, this is typical behavior for semantic-release/npm plugin and not inherently malicious.

lib/prepare.js:15
low

Process spawn

NPS-68EF952B8CA8

Spawns the 'npm publish' command via execa, which executes a subprocess. While this is expected behavior for a publishing library (semantic-release plugin), shell command execution is inherently risky if inputs are not properly sanitized. The arguments (basePath, npmrc, distTag, registry) are derived from package configuration and context rather than direct user input, but they are passed as separate arguments (not shell string), reducing injection risk.

lib/publish.js:24
low

Credential file access

NPS-A409563066C3

The npmrc path is passed to the npm publish command as '--userconfig'. This means the package interacts with npm credentials stored in .npmrc files. However, this is the standard mechanism for publishing to registries and does not itself indicate credential exfiltration, as the value is not read or transmitted elsewhere by this code.

lib/publish.js:24
low

Credential handling

NPS-0E690C66BE44

The code reads npm configuration files (.npmrc) which may contain authentication tokens, and writes them to a new .npmrc file. This is expected behavior for an npm authentication setup utility (likely from semantic-release/npm), but it does handle sensitive credentials. No exfiltration to external servers is observed.

lib/set-npmrc-auth.js
low

Environment variable usage

NPS-434777CB200C

Reads NPM_TOKEN and NPM_CONFIG_USERCONFIG environment variables to obtain registry authentication tokens. This is standard for npm publishing tools but constitutes credential access.

lib/set-npmrc-auth.js
low

File system write

NPS-463BF6F9B6FB

Writes to a file specified by the npmrc parameter, which is passed by the caller. This could potentially write outside the package scope if the caller provides an arbitrary path, but within context this is a configuration file managed by the tool.

lib/set-npmrc-auth.js
low

Legitimate network request with credential

NPS-1DABFF4F0228

The code fetches an OIDC token from GitHub Actions or GitLab Pipelines and exchanges it for an npm registry publish token via a POST request to the official npm registry endpoint. This is the standard npm Trusted Publishing flow. The token is sent only to the hardcoded official registry URL (OFFICIAL_REGISTRY constant), and the Authorization header uses a short-lived OIDC token, not a long-lived credential. No data exfiltration to third-party servers occurs.

lib/trusted-publishing/token-exchange.js

Files reviewed

FileVerdictWhat the reviewer saw
lib/get-registry.js medium Code is a benign npm registry resolver that reads npm config/env to determine the registry URL; no exfiltration, no code execution, no spawning — only low-to-medium concerns from touching .npmrc/environment variables.
lib/prepare.js medium This appears to be a legitimate semantic-release/npm plugin that spawns npm commands and moves tarballs, but it lacks input validation for paths like tarballDir and npmrc, which could lead to path traversal or credential exposure if those inputs are attacker-controlled.
lib/publish.js medium The code is a standard semantic-release npm publish plugin that spawns 'npm publish'; no malicious data exfiltration, obfuscation, or credential harvesting was detected.
lib/set-npmrc-auth.js medium Code handles npm authentication credentials as expected for a publishing utility, with no evidence of exfiltration, obfuscation, or malicious behavior.
lib/trusted-publishing/oidc-context.js medium The file implements a narrow OIDC token exchange gated on the official registry, with no direct malicious patterns, but its security depends on the unreviewed token-exchange dependency.
index.js safe This is the standard @semantic-release/npm plugin entry point; it orchestrates npm publish operations using modular helper functions and contains no malicious patterns such as data exfiltration, credential harvesting, dynamic code execution, or install-time backdoors.
lib/add-channel.js safe No malicious patterns detected; the code uses execa to run npm dist-tag commands as part of a legitimate release workflow, with no data exfiltration, credential harvesting, obfuscation, or other suspicious behavior.
lib/definitions/constants.js safe Cleared by Jev triage; no further analysis needed
lib/definitions/errors.js safe No malicious patterns detected in error definition helpers; code only builds static error messages using package metadata.
lib/get-channel.js safe Cleared by Jev triage; no further analysis needed
lib/get-error.js safe Cleared by Jev triage; no further analysis needed
lib/get-pkg.js safe Cleared by Jev triage; no further analysis needed
lib/get-release-info.js safe No malicious patterns detected; the code performs a read-only URL normalization and conditional string construction without network, filesystem, process, or environment-variable abuse.
lib/trusted-publishing/token-exchange.js safe The code implements npm's official OIDC token exchange for trusted publishing, interacting only with the official npm registry and using standard @actions/core and env-ci APIs with no malicious patterns detected.
lib/verify-auth.js safe No malicious patterns detected; this is legitimate semantic-release authentication verification code that spawns npm commands to validate registry tokens.
lib/verify-config.js safe Cleared by Jev triage; no further analysis needed

Frequently asked questions

Is @semantic-release/npm safe to use?

No confirmed malware was found in @semantic-release/npm@13.1.5, but the review flagged 5 medium, 9 low severity findings for risky patterns worth checking before you rely on it.

Does @semantic-release/npm contain malware?

No malware was identified in @semantic-release/npm@13.1.5 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 @semantic-release/npm checked?

Togoder Security downloaded the published npm package and had an AI model read its 16 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 @semantic-release/npm 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 @semantic-release/npm@13.1.5, cost nothing.

Related security reports