MCPInstall

npm-security-best-practices

Expert guidance on securing npm packages, preventing supply chain attacks, and hardening package manager configurations

Installs
920
Last 24h
—
Trending rank
—
Security
Not audited

Install

Works with every agent the skills CLI supports.

npx skills add https://github.com/reason-machines/security-skills --skill npm-security-best-practices
  1. 01

    Install

    Run the command in your project. The CLI asks which agents to install for.

  2. 02

    Describe the task

    Ask your agent for something this skill covers. It loads npm-security-best-practices automatically when relevant.

  3. 03

    Review the result

    The agent follows the SKILL.md steps, scripts and references bundled with the skill.

SKILL.md

The instructions your agent reads when the skill is triggered.

npm Security Best Practices

Skill by ara.so — Security Skills collection.

This skill provides expert guidance on securing npm package installations, preventing supply chain attacks, and implementing security best practices for Node.js development. Based on the comprehensive npm-security-best-practices repository by Lirantal.

Overview

The npm ecosystem is a frequent target for supply chain attacks including:

  • Shai-Hulud attacks - Worm-like propagation through compromised packages
  • Nx incident - Malicious code in postinstall scripts
  • event-stream attack - Long-running exfiltration via lifecycle scripts
  • Dependency confusion - Attackers publishing malicious packages with internal names

This skill covers configuration, tooling, and practices to mitigate these risks across npm, pnpm, and Bun.

Secure-by-Default Configuration

npm (.npmrc)

Create or update .npmrc in your project root or global config (~/.npmrc):

# Disable all lifecycle scripts (postinstall, preinstall, etc.)
ignore-scripts=true

# Block git-based dependencies (git+ssh://, git+https://, etc.)
allow-git=none

# Only install packages that have been published for at least 30 days
min-release-age=30

Apply globally:

npm config set ignore-scripts true
npm config set allow-git none
npm config set min-release-age 30

pnpm (pnpm-workspace.yaml)

Create pnpm-workspace.yaml in your project root:

# Block packages newer than 30 days (43200 minutes)
minimumReleaseAge: 43200

# Reject versions with regressed trust signals (pnpm 10.21+)
trustPolicy: no-downgrade

# Allowlist for packages that need build scripts
allowBuilds:
  esbuild: true
  rolldown: true
  nx@21.6.4 || 21.6.5: true

# Fail install if unlisted scripts try to run
strictDepBuilds: true

# Block git URLs in dependencies
blockExoticSubdeps: true

# Optional: ignore trust policy for legacy packages
trustPolicyIgnoreAfter: 43200

# Optional: exempt specific packages from trust policy
trustPolicyExclude:
  - 'chokidar@4.0.3'

Bun (package.json)

Bun disables postinstall scripts by default. To allow specific packages:

{
  "trustedDependencies": [
    "esbuild",
    "sharp",
    "fsevents"
  ]
}

Installation Commands

Secure npm install

# Install with security flags
npm install --ignore-scripts --allow-git=none

# Use npm ci for reproducible installs (CI/CD)
npm ci --ignore-scripts

# Install specific package securely
npm install lodash --ignore-scripts --allow-git=none

Secure pnpm install

# Install with workspace config enforced
pnpm install

# Review blocked packages
pnpm install --loglevel=verbose

# Bypass trust policy for specific install (use sparingly)
pnpm install --ignore-trust-policy

Selective script execution

Use @lavamoat/allow-scripts for granular control:

# Install the tool
npm install -g @lavamoat/allow-scripts

# Create allowlist
npx allow-scripts setup

# Edit package.json to add allowlist

Example package.json:

{
  "scripts": {
    "prepare": "allow-scripts"
  },
  "lavamoat": {
    "allowScripts": {
      "esbuild": true,
      "core-js": false,
      "nx>@nx/nx-linux-x64-gnu": true
    }
  }
}

Hardening npx Execution

# Execute without installing package
npx --no-install create-react-app my-app

# Use specific version to avoid typosquatting
npx create-react-app@5.0.1 my-app

# Verify package before running
npm view create-react-app
npx create-react-app my-app

# Use with security wrappers (see below)

Security Tooling Integration

npq - Package quality and security checks

# Install globally
npm install -g npq

# Use instead of npm install
npq install lodash

# Check package before installing
npq check lodash

Socket Firewall (sfw)

# Install globally
npm install -g @socketsecurity/cli

# Protect npm install
npx @socketsecurity/cli npm install

# Audit project dependencies
npx @socketsecurity/cli audit

# Check specific package
npx @socketsecurity/cli info lodash

Snyk - Vulnerability scanning

# Install CLI
npm install -g snyk

# Authenticate
snyk auth

# Test for vulnerabilities
snyk test

# Monitor project
snyk monitor

# Check for supply chain issues
snyk code test

Automated Dependency Updates with Cooldown

Renovate Bot (renovate.json)

{
  "extends": ["config:base"],
  "minimumReleaseAge": "30 days",
  "stabilityDays": 30,
  "prCreation": "not-pending",
  "packageRules": [
    {
      "matchUpdateTypes": ["major"],
      "minimumReleaseAge": "60 days"
    }
  ]
}

Dependabot (.github/dependabot.yml)

version: 2
updates:
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "weekly"
    # Dependabot doesn't support minimumReleaseAge natively
    # Use branch protection rules and manual delay
    open-pull-requests-limit: 10
    labels:
      - "dependencies"
      - "security"

Use GitHub Actions to enforce cooldown:

name: Dependency Cooldown Check
on:
  pull_request:
    paths:
      - 'package.json'
      - 'package-lock.json'

jobs:
  check-release-age:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Check package age
        run: |
          # Custom script to verify package age
          node scripts/check-package-age.js

Lockfile Security

Prevent lockfile injection

# Review lockfile changes in PRs
git diff package-lock.json

# Verify integrity
npm audit

# Regenerate if suspicious
rm package-lock.json
npm install --ignore-scripts

.gitattributes protection

# Prevent merge conflicts from hiding malicious changes
package-lock.json merge=binary
pnpm-lock.yaml merge=binary

Package Health Assessment

Snyk Advisor lookup

# Check package health
curl https://snyk.io/advisor/npm-package/lodash | jq

# CLI check
npx snyk-advisor lodash

Manual verification checklist

// check-package-health.js
const fetch = require('node-fetch');

async function checkPackage(packageName) {
  const response = await fetch(`https://registry.npmjs.org/${packageName}`);
  const data = await response.json();
  
  const latestVersion = data['dist-tags'].latest;
  const versionInfo = data.versions[latestVersion];
  
  console.log(`Package: ${packageName}@${latestVersion}`);
  console.log(`Published: ${versionInfo.time || 'N/A'}`);
  console.log(`Maintainers: ${data.maintainers?.length || 0}`);
  console.log(`License: ${versionInfo.license || 'NONE'}`);
  console.log(`Has scripts: ${!!versionInfo.scripts}`);
  console.log(`Dependencies: ${Object.keys(versionInfo.dependencies || {}).length}`);
  
  // Check provenance (npm 9.5+)
  if (versionInfo.dist?.attestations) {
    console.log('✓ Has provenance attestation');
  } else {
    console.log('⚠ No provenance attestation');
  }
}

checkPackage(process.argv[2]);

Run:

node check-package-health.js lodash

Preventing Dependency Confusion

.npmrc scoped registries

# Use private registry for org packages
@mycompany:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}

# Public packages from npm
registry=https://registry.npmjs.org/

package.json name scoping

{
  "name": "@mycompany/internal-lib",
  "version": "1.0.0",
  "publishConfig": {
    "registry": "https://npm.pkg.github.com"
  }
}

Dev Container Security

.devcontainer/devcontainer.json

{
  "name": "Secure Node.js Dev",
  "image": "mcr.microsoft.com/devcontainers/javascript-node:20",
  "features": {
    "ghcr.io/devcontainers/features/node:1": {
      "version": "20"
    }
  },
  "postCreateCommand": "npm config set ignore-scripts true && npm config set allow-git none",
  "remoteEnv": {
    "NPM_CONFIG_IGNORE_SCRIPTS": "true",
    "NPM_CONFIG_ALLOW_GIT": "none"
  },
  "mounts": [
    "source=${localEnv:HOME}/.npmrc,target=/home/node/.npmrc,type=bind,consistency=cached"
  ]
}

Environment Variable Security

Use .env.vault instead of plaintext .env

# Install dotenv-vault
npm install dotenv-vault

# Encrypt secrets
npx dotenv-vault local build

# Generate .env.vault (encrypted)
npx dotenv-vault push

# .gitignore update
echo ".env" >> .gitignore
echo ".env.*.vault" >> .gitignore

Access encrypted secrets

// app.js
require('dotenv-vault-core').config();

const apiKey = process.env.API_KEY; // Decrypted at runtime

Maintainer Best Practices

Enable 2FA on npm account

# Enable 2FA
npm profile enable-2fa auth-and-writes

# Verify status
npm profile get

Publish with provenance (npm 9.5+)

# Publish with provenance attestation
npm publish --provenance

# Verify in package.json before publishing
npm pack --dry-run

GitHub Actions OIDC publishing

# .github/workflows/publish.yml
name: Publish Package
on:
  release:
    types: [created]

jobs:
  publish:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          registry-url: 'https://registry.npmjs.org'
      - run: npm ci --ignore-scripts
      - run: npm publish --provenance --access public
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

Troubleshooting

Scripts are blocked but package needs them

Problem: A legitimate package requires postinstall scripts.

Solution: Use allowlist approach with @lavamoat/allow-scripts or pnpm allowBuilds:

# pnpm approach
# Add to pnpm-workspace.yaml
allowBuilds:
  problematic-package: true

# npm/yarn approach with lavamoat
npm install @lavamoat/allow-scripts
npx allow-scripts setup
# Edit package.json lavamoat.allowScripts section

Git dependency is required

Problem: Internal package only available via git URL.

Solution: Use private npm registry instead:

# Publish to GitHub Packages
echo "//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}" >> .npmrc
npm publish --registry=https://npm.pkg.github.com

# Or use Verdaccio for self-hosted registry
npm install -g verdaccio
verdaccio

Cooldown period blocks urgent security fix

Problem: Security patch released but blocked by min-release-age.

Solution: Temporarily override for specific package:

# npm - install specific version without min-release-age
npm install package@1.2.3 --no-min-release-age

# pnpm - add to trustPolicyExclude
# In pnpm-workspace.yaml:
trustPolicyExclude:
  - 'package@1.2.3'

Trust policy blocks legitimate package

Problem: pnpm trust policy rejects package downgrade.

Solution: Investigate first, then exempt if safe:

# Check what changed
npm view package@version dist.integrity
npm view package@old-version dist.integrity

# If legitimate, exempt in pnpm-workspace.yaml
trustPolicyExclude:
  - 'package@version'

False positive from security scanner

Problem: Snyk/Socket reports issue in vetted package.

Solution: Create exceptions with justification:

# .snyk
ignore:
  SNYK-JS-LODASH-12345:
    - lodash:
        reason: 'Prototype pollution not exploitable in our use case'
        expires: '2024-12-31'

CI/CD Integration

GitHub Actions security workflow

name: Security Audit
on: [push, pull_request]

jobs:
  security:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      
      - name: Install with security flags
        run: npm ci --ignore-scripts
      
      - name: Audit dependencies
        run: npm audit --audit-level=moderate
      
      - name: Check with Socket
        run: npx @socketsecurity/cli audit
        env:
          SOCKET_SECURITY_API_KEY: ${{ secrets.SOCKET_API_KEY }}
      
      - name: Snyk security scan
        run: npx snyk test --severity-threshold=high
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}

Additional Resources

FAQ

What does the npm-security-best-practices skill do?

Expert guidance on securing npm packages, preventing supply chain attacks, and hardening package manager configurations

How do I install npm-security-best-practices?

Run npx skills add https://github.com/reason-machines/security-skills --skill npm-security-best-practices in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/npm-security-best-practices/ (personal) or .claude/skills/npm-security-best-practices/ (project).

Which AI agents can use npm-security-best-practices?

Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.

Is npm-security-best-practices safe to install?

No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.

Who maintains npm-security-best-practices?

It is published by reason-machines in reason-machines/security-skills. It has 920 recorded installs.

More from reason-machines/security-skills

View all →

anthropic-cybersecurity-skills

reason-machines/security-skills

Use 754 structured cybersecurity skills mapped to MITRE ATT&CK, NIST CSF, ATLAS, D3FEND, and NIST AI RMF for AI-driven security operations

AI & Agents1.7K installs

pentest-ai-agents

reason-machines/security-skills

Claude Code subagents for offensive security research, penetration testing planning, recon analysis, exploit research, detection engineering, and security reporting

Security1.4K installs

pentest-agents-bug-bounty-framework

reason-machines/security-skills

Autonomous bug bounty agent framework with 50 agents, hunt loops, exploit chains, MCP servers for platform integration and writeup search

openosint-ai-osint-framework

reason-machines/security-skills

AI-powered OSINT agent with interactive REPL, MCP server, and CLI for email/username/domain/IP/phone investigation using 11 integrated tools

Backend & APIs1.2K installs

vibe-security-skill

reason-machines/security-skills

Agent skill that audits vibe-coded apps for common security vulnerabilities introduced by AI coding assistants

Security1.1K installs

openclaw-security-hardening

reason-machines/security-skills

Deploy and manage security hardening for high-privilege autonomous AI agents (OpenClaw) using zero-trust architecture and automated defense matrices

Security1.1K installs

Popular security skills

View category →

azure-compliance

microsoft/azure-skills

Run Azure compliance and security audits with azqr plus Key Vault expiration checks. Covers best-practice assessment, resource review, policy/compliance validation, and security posture checks. WHEN: compliance scan, security audit, BEFORE running azqr (compliance cli tool), Azure best practices, Key Vault expiration check, expired certificates, expiring secrets, orphaned resources, compliance assessment.

OfficialSecurity567K installs

minimal-run-and-audit

lllllllama/rigorpilot-skills

Rigor Run skill for README-first deep learning repo reproduction. Use when the task is specifically to capture or normalize evidence from the selected smoke test or documented inference or evaluation command and write standardized reprooutputs/ files, including patch notes when repository files changed. Do not use for training execution, initial repo intake, generic environment setup, paper lookup, target selection, hidden scientific-meaning changes, or end-to-end orchestration by itself.

Security477.4K installs

seo-audit

coreyhaines31/marketingskills

When the user wants to audit, review, or diagnose SEO issues on their site. Also use when the user mentions "SEO audit," "technical SEO," "why am I not ranking," "SEO issues," "on-page SEO," "meta tags review," "SEO health check," "my traffic dropped," "lost rankings," "not showing up in Google," "site isn't ranking," "Google update hit me," "page speed," "core web vitals," "crawl errors," "indexing issues," "stuck on page 2," "striking distance keywords," "title tag rewrite," "low CTR," "local SEO," "Google Business Profile," or "map pack." Use this even if the user just says something vague like "my SEO is bad" or "help with SEO" — start with an audit. For building pages at scale to target keywords, see programmatic-seo. For adding structured data, see schema. For AI search optimization, see ai-seo.

Security238.7K installs

firebase-security-rules-auditor

firebase/agent-skills

Audits Firebase (Firestore, Cloud Storage) security rules for vulnerabilities, privilege escalation, role bypasses, create vs update inconsistencies, resource exhaustion, type safety, size limits, and hasOnly ownership checks. Use when auditing/reviewing rules, running red-team rule assessments, or scoring against auditor checklists. Don't use for Firebase CLI (login, deploy), Auth, Crashlytics, Remote Config, or database queries.

OfficialSecurity139.1K installs

audit

pbakaus/impeccable

Run technical quality checks across accessibility, performance, theming, responsive design, and anti-patterns. Generates a scored report with P0-P3 severity ratings and actionable plan. Use when the user wants an accessibility check, performance audit, or technical quality review.

Security81.9K installs

competitors

coreyhaines31/marketingskills

When the user wants to create competitor comparison or alternative pages for SEO and buyer-facing use. Also use when the user mentions 'alternative page,' 'vs page,' 'competitor comparison,' 'comparison page,' '[Product] vs [Product],' '[Product] alternative,' 'competitive landing pages,' 'how do we compare to X,' 'competitor teardown,' 'audit our competitor pages,' 'are our comparison pages out of date,' or 'competitive asset audit.' Use this for any content that positions your product against competitors. Covers four formats: singular alternative, plural alternatives, you vs competitor, and competitor vs competitor. For auditing existing claims (not researching competitors from scratch, which is competitor-profiling; not technical SEO on these pages, which is seo-audit), use the asset audit here. For internal battle cards and sales-specific competitor docs, see sales-enablement.

Security79.3K installs