{"id":31228150,"url":"https://github.com/bodadotsh/npm-security-best-practices","last_synced_at":"2025-09-27T12:01:24.699Z","repository":{"id":315972553,"uuid":"1060866328","full_name":"bodadotsh/npm-security-best-practices","owner":"bodadotsh","description":"A list to stay safe from NPM supply chain attacks","archived":false,"fork":false,"pushed_at":"2025-09-21T23:03:02.000Z","size":1289,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-09-22T00:19:17.223Z","etag":null,"topics":["deno","javascript","list","nodejs","npm","pnpm","security","yarn"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bodadotsh.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-20T18:50:13.000Z","updated_at":"2025-09-21T23:13:46.000Z","dependencies_parsed_at":"2025-09-22T00:19:19.390Z","dependency_job_id":"13ac36ea-c526-49a7-80ca-e492aa59571c","html_url":"https://github.com/bodadotsh/npm-security-best-practices","commit_stats":null,"previous_names":["bodadotsh/npm-security-best-practices"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/bodadotsh/npm-security-best-practices","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bodadotsh%2Fnpm-security-best-practices","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bodadotsh%2Fnpm-security-best-practices/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bodadotsh%2Fnpm-security-best-practices/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bodadotsh%2Fnpm-security-best-practices/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bodadotsh","download_url":"https://codeload.github.com/bodadotsh/npm-security-best-practices/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bodadotsh%2Fnpm-security-best-practices/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":276348330,"owners_count":25626605,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-22T02:00:08.972Z","response_time":79,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["deno","javascript","list","nodejs","npm","pnpm","security","yarn"],"created_at":"2025-09-22T05:13:15.351Z","updated_at":"2025-09-24T07:05:46.071Z","avatar_url":"https://github.com/bodadotsh.png","language":null,"funding_links":["https://github.com/sponsors","https://opencollective.com","https://thanks.dev"],"categories":["Other Lists"],"sub_categories":["TeX Lists"],"readme":"![npm meme](./npm_meme.png)\n\n# NPM Security Best Practices\n\n\u003e [!NOTE]  \n\u003e The NPM ecosystem is no stranger to compromises[^1][^2], supply-chain attacks[^3], malware[^4][^5], spam[^6], phishing[^7], incidents[^8] or even trolls[^9]. In this repository, I have consolidated a list of information you might find useful in securing yourself against these incidents.\n\u003e\n\u003e Feel free to submit a Pull Request, or reach out to me on [Twitter](https://x.com/bodadotsh)!\n\n\u003e [!TIP]\n\u003e This repository covers `npm`, `bun`, `deno`, `pnpm`, `yarn` and more.\n\n\u003ca href=\"https://news.ycombinator.com/item?id=45326754\"\u003e\n\u003cimg src=\"https://img.shields.io/badge/hacker%20news%20discussion-ff6600\" alt=\"hn discussion\"/\u003e\n\u003c/a\u003e\n\n## Table of Contents\n\n- [For Developers](#for-developers)\n  - [1. Pin dependency versions](#1-pin-dependency-versions)\n  - [2. Include lockfiles](#2-include-lockfiles)\n  - [3. Disable lifecycle scripts](#3-disable-lifecycle-scripts)\n  - [4. Set minimal release age](#4-set-minimal-release-age)\n  - [5. Permission model](#5-permission-model)\n  - [6. Reduce external dependencies](#6-reduce-external-dependencies)\n- [For Maintainers](#for-maintainers)\n  - [7. Enable 2FA](#7-enable-2fa)\n  - [8. Create tokens with limited access](#8-create-tokens-with-limited-access)\n  - [9. Generate provenance statements](#9-generate-provenance-statements)\n  - [10. Review published files](#10-review-published-files)\n- [Miscellaneous](#miscellaneous)\n  - [11. NPM organization](#11-npm-organization)\n  - [12. Use private registry](#12-use-private-registry)\n  - [13. Audit, monitor and security tools](#13-audit-monitor-and-security-tools)\n  - [14. Support OSS](#14-support-oss)\n\n## For Developers\n\n\u003e [!TIP]\n\u003e Here's a [sample `.npmrc` file](.npmrc) with the config options mentioned below:\n\u003e\n\u003e ```\n\u003e ignore-scripts=true\n\u003e provenance=true\n\u003e save-exact=true\n\u003e save-prefix=''\n\u003e ```\n\u003e\n\u003e And other configuration files examples are here:\n\u003e\n\u003e - [`bunfig.toml`](bunfig.toml)\n\u003e - [`pnpm-workspace.yaml`](pnpm-workspace.yaml)\n\u003e - [`deno.json`](deno.json)\n\u003e - [`.yarnrc.yml`](.yarnrc.yml)\n\n### 1. Pin Dependency Versions\n\n\u003e On `npm`, by default, a new dependency will be installed with the Caret `^` operator. This operator installs the most recent `minor` or `patch` releases. E.g., `^1.2.3` will install `1.2.3`, `1.6.2`, etc. See https://docs.npmjs.com/about-semantic-versioning and try out the npm SemVer Calculator (https://semver.npmjs.com).\n\nHere's how to pin exact version in various package managers:\n\n```sh\nnpm install --save-exact react\npnpm add --save-exact react\nyarn add --save-exact react\nbun add --exact react\ndeno add npm:react@19.1.1\n```\n\nWe can also update this setting in configuration files (e.g., [`.npmrc`](https://docs.npmjs.com/cli/v11/configuring-npm/npmrc)), with either [`save-exact`](https://docs.npmjs.com/cli/v11/using-npm/config#save-exact) or [`save-prefix`](https://docs.npmjs.com/cli/v11/using-npm/config#save-prefix) key and value pairs:\n\n```sh\nnpm config set save-exact=true\npnpm config set save-exact true\nyarn config set defaultSemverRangePrefix \"\"\n```\n\nFor `bun`, the config file is `bunfig.toml` and corresponding config is:\n\n```toml\n[install]\nexact = true\n```\n\n#### Override the transitive dependencies\n\n\u003e **_However_**, our direct dependencies also have their own dependencies (_transitive_ dependencies). Even if we pin our direct dependencies, their transitive dependencies might still use broad version range operators (like `^` or `~`). The solution is to override the transitive dependencies: https://docs.npmjs.com/cli/v11/configuring-npm/package-json#overrides\n\nIn `package.json`, if we have the following `overrides` field:\n\n```json\n{\n  \"dependencies\": {\n    \"library-a\": \"^3.0.0\"\n  },\n  \"overrides\": {\n    \"lodash\": \"4.17.21\"\n  }\n}\n```\n\n- Let's assume that `⁠library-a`'s `⁠package.json` has a dependency on `\"lodash\": \"^4.17.0\"`\n- Without the `⁠overrides` section, `⁠npm` might install `⁠lodash@4.17.22` (or any of the latest `⁠4.x.x` versions) as a transitive dependency of `⁠library-a`\n- However, by adding `\"overrides\": { \"lodash\": \"4.17.21\" }`, we are telling `⁠npm` that anywhere `⁠lodash` appears in the dependency tree, it must be resolved to exactly version `⁠4.17.21`\n\nFor `pnpm`, we can also define the `overrides` field in the `pnpm-workspace.yaml` file: https://pnpm.io/settings#overrides\n\nFor `yarn`, the `resolutions` field is introduced before the `overrides` field, and it also offers a similar functionality: https://yarnpkg.com/configuration/manifest#resolutions\n\n```json\n{\n  \"resolutions\": {\n    \"lodash\": \"4.17.21\"\n  }\n}\n```\n\n```sh\n# yarn also provide a cli to set the resolution: https://yarnpkg.com/cli/set/resolution\nyarn set resolution \u003cdescriptor\u003e \u003cresolution\u003e\n```\n\nFor `bun`, it supports either the `overrides` field or the `resolutions` field: https://bun.com/docs/install/overrides\n\nFor `deno`, see https://github.com/denoland/deno/issues/28664 for more details.\n\n### 2. Include Lockfiles\n\n\u003e Ensure to commit package managers lockfiles to `git` and share between different environments. Different lockfiles are: `package-lock.json` for `npm`, `pnpm-lock.yaml` for `pnpm`, `bun.lock` for `bun`, `yarn.lock` for `yarn` and `deno.lock` for `deno`.\n\u003e\n\u003e In automated environments such as continuous integration and deployments, we should install the exact dependencies as defined in the lockfile.\n\n```sh\nnpm ci\nbun install --frozen-lockfile\nyarn install --frozen-lockfile\ndeno install --frozen\n```\n\nFor `deno`, we can also set the following in a `deno.json` file:\n\n```json\n{\n  \"lock\": {\n    \"frozen\": true\n  }\n}\n```\n\n### 3. Disable Lifecycle Scripts\n\n\u003e Lifecycle scripts are special scripts that happen in addition to the `pre\u003cevent\u003e`, `post\u003cevent\u003e`, and `\u003cevent\u003e` scripts. For instance, `preinstall` is run before `install` is run and `postinstall` is run after `install` is run. See how npm handles the \"scripts\" field: https://docs.npmjs.com/cli/v11/using-npm/scripts#life-cycle-scripts\n\u003e\n\u003e Lifecycle scripts are a common strategy from malicious actors. For example, the \"Shai-Hulud\" worms[^3] edit the `package.json` file to add a `postinstall` script that would then steal credentials.\n\n```sh\nnpm config set ignore-scripts true --global\nyarn config set enableScripts false\n```\n\nFor `bun`, `deno` and `pnpm`, they are disabled by default.\n\n\u003e [!NOTE]\n\u003e\n\u003e For `bun`, the [top 500 npm packages](https://github.com/oven-sh/bun/blob/main/src/install/default-trusted-dependencies.txt) with lifecycle scripts are allowed by default. \n\n\u003e [!TIP]\n\u003e We can combine many of the flags above. For example, the following `npm` command would install only production dependencies as defined in the lockfile and ignore lifecycle scripts:\n\u003e\n\u003e `npm ci --omit=dev --ignore-scripts`\n\n### 4. Set Minimal Release Age\n\n\u003e We can set a delay to avoid installing newly published packages. This applies to all dependencies, including transitive ones. For example, `pnpm v10.16` introduced the `minimumReleaseAge` option: https://pnpm.io/settings#minimumreleaseage, which defines the minimum number of minutes that must pass after a version is published before pnpm will install it. If `minimumReleaseAge` is set to `1440`, then pnpm will not install a version that was published less than 24 hours ago.\n\n```sh\npnpm config set minimumReleaseAge \u003cminutes\u003e\n\n# only install packages published at least 1 day ago\nnpm install --before=\"$(date -v -1d)\"\n\nyarn config set npmMinimalAgeGate \u003cminutes\u003e\n```\n\nFor `pnpm`, there's also a `minimumReleaseAgeExclude` option to exclude certain packages from the minimum release age.\n\nFor `npm`, there is [a proposal](https://github.com/npm/cli/issues/8570) to add `minimumReleaseAge` option and `minimumReleaseAgeExclude` option.\n\nFor `yarn`, config options `npmMinimalAgeGate` and `npmPreapprovedPackages` are implemented since [`v4.10.0`](https://github.com/yarnpkg/berry/releases/tag/%40yarnpkg%2Fcli%2F4.10.0).\n\nFor `bun`, it is discussed here: https://github.com/oven-sh/bun/issues/22679\n\nFor `deno`, an draft proposal is here: https://github.com/denoland/deno/pull/30752\n\nExamples of other tools that offer similar functionality:\n\n- npm-check-updates (https://github.com/raineorshine/npm-check-updates) has the `--cooldown` flag.\n- Renovate CLI (https://github.com/renovatebot/renovate) has a [`minimumReleaseAge`](https://docs.renovatebot.com/configuration-options/#minimumreleaseage) config option.\n- Step Security (https://www.stepsecurity.io) has a [NPM Package Cooldown Check](https://www.stepsecurity.io/blog/introducing-the-npm-package-cooldown-check) feature.\n\n### 5. Permission Model\n\n\u003e In the latest LTS version of `nodejs`, we can use the Permission model to control what system resources a process has access to or what actions the process can take with those resources. **_However_**, this does not provide security guarantees in the presence of malicious code. Malicious code can still bypass the permission model and execute arbitrary code without the restrictions imposed by the permission model.\n\nRead about the Node.js permission model: https://nodejs.org/docs/latest/api/permissions.html\n\n```sh\n# by default, granted full access\nnode index.js\n\n# restrict access to all available permissions\nnode --permission index.js\n\n# enable specific permissions\nnode --permission --allow-fs-read=* --allow-fs-write=* index.js\n\n# use permission model with `npx`\nnpx --node-options=\"--permission\" \u003cpackage-name\u003e\n```\n\nDeno enables permissions by default. See https://docs.deno.com/runtime/fundamentals/security/\n\n```sh\n# by default, restrict access\ndeno run script.ts\n\n# enable specific permission\ndeno run --allow-read script.ts\n```\n\nFor Bun, the permission model is currently discussed [here](https://github.com/oven-sh/bun/discussions/725) and [here](https://github.com/oven-sh/bun/issues/6617).\n\n### 6. Reduce External Dependencies\n\n\u003e Because `npm` has a low barrier for publishing packages, the ecosystem quickly grew to be the biggest package registry with over 5 million packages to date[^11]. But not all packages are created equal. There are small utility packages[^8] that are downloaded as dependencies when we could write them ourselves and raise the question of \"have we forgotten how to code?[^12]\"\n\nBetween `nodejs`, `bun` and `deno`, developers can use many of their modern features instead of relying on third-party libraries. The native modules may not provide the same level of functionality, but they should be considered whenever possible. Here are few examples:\n\n| NPM libraries                     | Built-in modules                                                   |\n| --------------------------------- | ------------------------------------------------------------------ |\n| `axios`, `node-fetch`, `got`, etc | native`fetch` API                                                  |\n| `jest`, `mocha`, `ava`, etc       | `node:test`,`node:assert`, `bun test` and `deno test`              |\n| `nodemon`, `chokidar`, etc        | `node --watch`, `bun --watch` and `deno --watch`                   |\n| `dotenv`, `dotenv-expand`, etc    | `node --env-file`, `bun --env-file` and `deno --env-file`          |\n| `typescript`, `ts-node`, etc      | `node --experimental-strip-types`[^10], native to `deno` and `bun` |\n| `esbuild`, `rollup`, etc          | `bun build` and `deno bundle`                                      |\n| `prettier`, `eslint`, etc         | `deno lint` and `deno fmt`                                         |\n\nHere are some resources that you might find useful:\n\n- https://obsidian.md/blog/less-is-safer\n- https://kashw1n.com/blog/nodejs-2025\n- https://lyra.horse/blog/2025/08/you-dont-need-js\n- https://blog.greenroots.info/10-lesser-known-web-apis-you-may-want-to-use\n- https://github.com/you-dont-need/You-Dont-Need-Momentjs\n- Visualise NPM dependencies: https://npmgraph.js.org\n- Knip (remove unused dependencies): https://github.com/webpro-nl/knip\n\n## For Maintainers\n\n### 7. Enable 2FA\n\nhttps://docs.npmjs.com/about-two-factor-authentication\n\n\u003e Two factor authentication (2FA) adds an extra layer of authentication to your `npm` account. 2FA is not required by default, but it is a good practice to enable it.\n\n```sh\n# ensure that 2FA is enabled for auth and writes (this is the default)\nnpm profile enable-2fa auth-and-writes\n```\n\n| Automation level | Package publishing access                                                                                                                     |\n| ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |\n| Manual           | Set each package access to `Require 2FA` and `Disable Tokens`                                                                                 |\n| Automatic        | Set each package access to `Require two-factor authentication` OR `Single factor automation tokens` OR `Single factor granular access tokens` |\n\n\u003e [!IMPORTANT]\n\u003e\n\u003e It is advised to configure a security-key that support [WebAuthn](https://caniuse.com/?search=webauthn), instead of time-based one-time password (TOTP)[^17]\n\n### 8. Create Tokens with Limited Access\n\nhttps://docs.npmjs.com/about-access-tokens#about-granular-access-tokens\n\n\u003e An access token is a common way to authenticate to `npm` when using the API or the `npm` CLI.\n\n```sh\nnpm token create # for a read and publish token\nnpm token create --read-only # for a read-only token\nnpm token create --cidr=[list] # for a CIDR-restricted read and publish token\nnpm token create --read-only --cidr=[list] # for a CIDR-restricted read-only token\n```\n\n\u003e [!IMPORTANT]\n\u003e Granular Access Tokens should be used instead of Legacy Tokens. Legacy tokens cannot be scoped and don't automatically expire. They're considered dangerous to use.\n\u003e\n\u003e - Restrict token to specific packages, scopes, and organizations\n\u003e - Set a token expiration date (e.g., annually)\n\u003e - Limit token access based on IP address ranges (CIDR notation)\n\u003e - Select between read-only or read and write access\n\u003e - Don't use the same token for multiple purposes\n\u003e - Descriptive token names\n\n### 9. Generate Provenance Statements\n\nhttps://docs.npmjs.com/generating-provenance-statements\n\n\u003e The _provenance attestation_ is established by publicly providing a link to a package's source code and build instructions from the build environment. This allows developers to verify where and how your package was built before they download it.\n\u003e\n\u003e The _publish attestations_ are generated by the registry when a package is published by an authorized user. When an npm package is published with provenance, it is signed by Sigstore public good servers and logged in a public transparency ledger, where users can view this information.\n\u003e\n\u003e For example, here's what a provenance statement look like on the `vue` package page: https://www.npmjs.com/package/vue#provenance\n\nTo establish provenance, use a supported CI/CD provider (e.g., GitHub Actions) and publish with the correct flag:\n\n```sh\nnpm publish --provenance\n```\n\nTo publish without evoking the `npm publish` command, we can do one of the following:\n\n- Set `NPM_CONFIG_PROVENANCE` to `true` in CI/CD environment\n- Add `provenance=true` to `.npmrc` file\n- Add `publishConfig` block to `package.json`\n\n```json\n\"publishConfig\": {\n  \"provenance\": true\n}\n```\n\nFor those interested in [Reproducible Builds](https://reproducible-builds.org), check out OSS Rebuild (https://github.com/google/oss-rebuild) and the Supply-chain Levels for Software Artifacts (SLSA) framework (https://slsa.dev).\n\n#### Trusted Publishing\n\nWhen using OpenID Connect (OIDC) auth, one can publish packages _without_ npm tokens, and get _automatic_ provenance. This is called **trusted publishing** and read the GitHub announcement here: https://github.blog/changelog/2025-07-31-npm-trusted-publishing-with-oidc-is-generally-available/ and https://docs.npmjs.com/trusted-publishers\n\n\u003e [!IMPORTANT]\n\u003e\n\u003e It is recommended to use trusted publishing instead of tokens[^17].\n\n### 10. Review Published Files\n\n\u003e Limiting the files in an npm package helps prevent malware by reducing the attack surface, and it avoids accidental leaking of sensitive data\n\nThe `files` field in `package.json` is used to specify the files that should be included in the published package. Certain files are always included, see: https://docs.npmjs.com/cli/v11/configuring-npm/package-json#files for more details.\n\n```json\n{\n  \"name\": \"my-package\",\n  \"version\": \"1.0.0\",\n  \"main\": \"dist/index.js\",\n  \"files\": [\"dist\", \"LICENSE\", \"README.md\"]\n}\n```\n\n\u003e [!TIP]\n\u003e\n\u003e The `.npmignore` file can also be used to exclude files from the published package. It will not override the `\"files\"` field, but in subdirectories it will.\n\u003e \n\u003e The `.npmignore` file works just like a `.gitignore`. If there is a `.gitignore` file, and `.npmignore` is missing, `.gitignore`'s contents will be used instead.\n\nRun `npm pack --dry-run` or `npm publish --dry-run` to see what would happen when we run the pack or publish command.\n\n```sh\n\u003e npm pack --dry-run\nnpm notice Tarball Contents\nnpm notice 1.1kB LICENSE\nnpm notice 1.9kB README.md\nnpm notice 108B index.js\nnpm notice 700B package.json\nnpm notice Tarball Details\n```\n\nIn `deno.json`, use the `publish.include` and `publish.exclude` fields to specify the files that should be included or excluded:\n\n```json\n{\n  \"publish\": {\n    \"include\": [\"dist/\", \"README.md\", \"deno.json\"],\n    \"exclude\": [\"**/*.test.*\"]\n  }\n}\n```\n\n## Miscellaneous\n\n### 11. NPM Organization\n\nhttps://docs.npmjs.com/organizations\n\nAt the organization level, best practices are:\n\n- Enable `Require 2FA` at the Organization Level\n- Minimise the number of `npm` Organization members\n- If multiple package teams in same organization, set the `developers` Team permission for all packages to `READ`\n- Create separate Teams to manage permissions for each package\n\n### 12. Use Private Registry\n\n\u003e Private package registries are a great way for organizations to manage their own dependencies, and can acts as a proxy to the public `npm` registry. Organizations can enforce security policies and vet packages before they are used in a project.\n\nHere are some private registries that you might find useful:\n\n- GitHub Packages https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-npm-registry\n- Verdaccio https://github.com/verdaccio/verdaccio\n- Vlt https://www.vlt.sh/\n- JFrog Artifactory https://jfrog.com/integrations/npm-registry\n- Sonatype: https://help.sonatype.com/en/npm-registry.html\n\n### 13. Audit, Monitor and Security Tools\n\n#### Audit\n\n\u003e Many package managers provide audit functionality to scan your project's dependencies for known security vulnerabilities, show a report and recommend the best way to fix them.\n\n```sh\nnpm audit # audit dependencies\nnpm audit fix # automatically install any compatible updates\nnpm audit signatures # verify the signatures of the dependencies\n\npnpm audit\npnpm audit --fix\n\nbun audit\n\nyarn npm audit\nyarn npm audit --recursive # audit transitive dependencies\n```\n\n#### GitHub\n\nhttps://github.com/security\n\nGitHub offers several services that can help protect against `npm` malwares, including:\n\n- [Dependabot](https://docs.github.com/en/code-security/getting-started/dependabot-quickstart-guide): This tool automatically scans your project's dependencies, including `npm` packages, for known vulnerabilities.\n- [Software Bill of Materials (SBOMs)](https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/exporting-a-software-bill-of-materials-for-your-repository): GitHub allows you to export an SBOM for your repository directly from its dependency graph. An SBOM provides a comprehensive list of all your project's dependencies, including transitive ones (dependencies of your dependencies).\n- [Code Scanning](https://docs.github.com/en/code-security/code-scanning/introduction-to-code-scanning/about-code-scanning): Code scanning can also help identify potential vulnerabilities or suspicious patterns that might arise from integrating compromised `npm` packages.\n\n\u003e [!WARNING]\n\u003e If you spot vulnerabilities or issues in NPM or Github, please report them using the following links:\n\u003e\n\u003e - https://docs.npmjs.com/reporting-malware-in-an-npm-package\n\u003e - https://docs.github.com/en/communities/maintaining-your-safety-on-github/reporting-abuse-or-spam#reporting-a-repository\n\n#### Socket.dev\n\nhttps://socket.dev\n\nSocket.dev is a security platform that protects code from both vulnerable and malicious dependencies. It offers various tools such as a [GitHub App](https://socket.dev/features/github) scans pull requests, [CLI tool](https://socket.dev/features/cli), [web extension](https://socket.dev/features/web-extension), [VSCode extension](https://docs.socket.dev/docs/socket-for-vs-code) and more. Here's their talk on [AI powered malware hunting at scale, Jan 2025](https://youtu.be/cxJPiMwoIyY).\n\n#### Snyk\n\nhttps://snyk.io\n\nSnyk offers a suite of tools to fix vulnerabilities in open source dependencies, including a CLI to run vulnerability scans on local machine, IDE integrations to embed into development environment, and API to integrate with Snyk programmatically. For example, you can [test public npm packages before use](https://docs.snyk.io/developer-tools/snyk-cli/scan-and-maintain-projects-using-the-cli/test-public-npm-packages-before-use) or [create automatic PRs for known vulnerabilities](https://docs.snyk.io/scan-with-snyk/pull-requests/snyk-pull-or-merge-requests/create-automatic-prs-for-backlog-issues-and-known-vulnerabilities-backlog-prs).\n\n### 14. Support OSS\n\n\u003e Maintainer burnout is a significant problem in the open-source community. Many popular `npm` packages are maintained by volunteers who work in their spare time, often without any compensation. Over time, this can lead to exhaustion and a lack of motivation, making them more susceptible to social engineering where a malicious actor pretends to be a helpful contributor and eventually injects malicious code.\n\n\u003e In 2018, the `event-stream` package was compromised due to the maintainer giving access to a malicious actor[^13]. Another example outside the JavaScript ecosystem is the XZ Utils incident[^14] in 2024 where a malicious actor worked for over three years to attain a position of trust.\n\n\u003e OSS donations also help create a more sustainable model for open-source development. Foundations can help support the business, marketing, legal, technical assistance and direct support behind hundreds of open source projects that so many rely upon[^15][^16].\n\nIn the JavaScript ecosystem, the OpenJS Foundation (https://openjsf.org) was founded in 2019 from a merger of JS Foundation and Node.js Foundation to support some of the most important JS projects. And few other platforms are listed below where you can donate and support the OSS you use everyday:\n\n- GitHub Sponsors https://github.com/sponsors\n- Open Collective https://opencollective.com\n- Thanks.dev https://thanks.dev\n- Open Source Pledge https://opensourcepledge.com\n\n[^1]: https://www.aikido.dev/blog/npm-debug-and-chalk-packages-compromised\n[^2]: https://socket.dev/blog/nx-packages-compromised\n[^3]: https://socket.dev/blog/ongoing-supply-chain-attack-targets-crowdstrike-npm-packages\n[^4]: https://www.reversinglabs.com/blog/malicious-npm-patch-delivers-reverse-shell\n[^5]: https://socket.dev/blog/north-korean-apt-lazarus-targets-developers-with-malicious-npm-package\n[^6]: https://socket.dev/blog/npm-registry-spam-john-wick\n[^7]: https://github.com/duckdb/duckdb-node/security/advisories/GHSA-w62p-hx95-gf2c\n[^8]: https://en.wikipedia.org/wiki/Npm_left-pad_incident\n[^9]: https://socket.dev/blog/when-everything-becomes-too-much\n[^10]: https://nodejs.org/en/learn/typescript/run-natively\n[^11]: https://libraries.io/npm\n[^12]: https://www.theregister.com/2016/03/29/npmgate_followup\n[^13]: https://github.com/dominictarr/event-stream/issues/116\n[^14]: https://en.wikipedia.org/wiki/XZ_Utils_backdoor\n[^15]: https://openssf.org/blog/2024/04/15/open-source-security-openssf-and-openjs-foundations-issue-alert-for-social-engineering-takeovers-of-open-source-projects/\n[^16]: https://xkcd.com/2347\n[^17]: https://github.blog/security/supply-chain-security/our-plan-for-a-more-secure-npm-supply-chain\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbodadotsh%2Fnpm-security-best-practices","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbodadotsh%2Fnpm-security-best-practices","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbodadotsh%2Fnpm-security-best-practices/lists"}