agentsclimarketplace

50 dependency supply chain review

Skill FluxonLab/Skillry/plugins/security/skills/50-dependency-supply-chain-review

Installable, permission-bounded, multi-platform agent skills & subagents for Claude Code, Codex, Copilot & Gemini/Antigravity — 125 skills + 73 subagents across 18 departments, with a validation harness, native plugin marketplace, and full upstream attribution. by FluxonLab.

Install
npx -y skills add FluxonLab/Skillry --skill 50-dependency-supply-chain-review

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Use when you need to review dependencies, scripts, lockfiles, package provenance, and install-time risks.

SKILL.md

14.0 KB, as published. Nobody here has run it

Dependency Supply Chain Review

Purpose

Audit the project's package dependency graph for known CVEs, suspicious install-time scripts, lockfile integrity issues, typosquatting candidates, outdated packages with breaking changes, and transitive dependency risks. Every finding gets a severity, a concrete package reference, and a prioritized remediation step. The audit is read-only and non-destructive — no packages are installed, upgraded, or removed without explicit user approval.

A dependency review that only runs npm audit and lists the output is not sufficient. The goal is to assess exploitability in context (a server-side RCE in a browser-only bundle is different from one in a server process), to check install-time code execution, to verify lockfile integrity, and to identify structural supply-chain risks such as namespace confusion or unreviewed postinstall scripts.

When to use

  • npm audit, yarn audit, or pip-audit has flagged vulnerabilities and you need a structured remediation plan.
  • A PR adds or upgrades packages and you want to verify supply-chain safety before merge.
  • The project has not had a dependency review in more than 90 days.
  • A postinstall or prepare script in a dependency is executing code at install time.
  • The lockfile (package-lock.json, yarn.lock, poetry.lock, pnpm-lock.yaml) is missing or was recently deleted and regenerated.
  • A security incident or CVE disclosure has named a package in the project's dependency tree.

When not to use

  • The project has no third-party dependencies (single-file scripts, standard-library only).
  • You need to audit application runtime logic unrelated to packages.
  • A dedicated security scanning tool (Snyk, Dependabot, Socket) has already triaged all findings and the task is to implement fixes — use a code-editing skill instead.

Procedure

  1. Confirm lockfile presence and integrity. Check that package-lock.json / yarn.lock / pnpm-lock.yaml / poetry.lock exists and is committed. A missing lockfile means installs are non-deterministic. Verify the lockfile was generated by the matching tool and version (check lockfileVersion in package-lock.json — v3 for npm 7+).

  2. Run the audit non-destructively. Execute npm audit --json or yarn audit --json and capture the output to a temp file. Do not run npm audit fix --force without reviewing the proposed changes. For Python, run pip-audit --format json. For Go, run govulncheck ./....

  3. Classify each CVE by exploitability in this project. For every finding, determine:

    • Severity (critical/high/moderate/low) as reported by the registry.
    • Is the vulnerable code path reachable in this project? A server-side RCE in a package only imported in a browser bundle that never runs on the server is unexploitable in that context.
    • Is a non-breaking fix version available? Record whether the fix is a patch, minor, or major bump.
  4. Inspect install-time scripts. For every dependency with postinstall, prepare, preinstall, or install scripts in its package.json, read what the script does. Flag any that download binaries, execute curl/wget, modify system files, or phone home. Legitimate packages like esbuild and puppeteer download platform-specific binaries — verify the download uses a checksum.

  5. Check for typosquatting candidates. Compare recently added package names against their intended counterparts: lodash vs l0dash, express vs expres. Pay special attention to packages added in the last PR with few public downloads or a short publish history. Use the npm registry API to check download counts and creation dates.

  6. Audit transitive dependency pinning. For CVEs in transitive (indirect) dependencies where a direct upgrade cannot resolve the issue, check whether overrides (npm 8+) or resolutions (yarn) can pin the safe transitive version. Document which CVEs are unresolvable without a major dependency change.

  7. Verify CI uses a reproducible install command. npm ci fails when the lockfile is out of sync with package.json, ensuring reproducibility. npm install silently updates the lockfile. CI pipelines must use npm ci (or yarn install --frozen-lockfile / pnpm install --frozen-lockfile).

  8. Check for outdated major versions. Run npm outdated and flag packages more than one major version behind, especially those with known end-of-life status (e.g., a runtime version past its LTS window, a framework version with no security patches).

  9. Review private registry configuration. If .npmrc configures a private registry scope, confirm it is scoped to the organization's namespace (e.g., @company/*) and does not redirect all traffic through an untrusted registry. Unscoped private registry config enables dependency confusion attacks where a public package with the same name and a higher version takes precedence.

  10. Document approved exceptions. For CVEs assessed as not exploitable in context, create or update an audit exception file (e.g., npm-audit-exceptions.json or .auditignore) with the CVE ID, the package, the reason for the exception, the reviewer's name, and the review date.

Concrete checks

  • Lockfile present, committed, and matches the package manager version (check lockfileVersion field).
  • npm audit (or equivalent) returns zero critical or high findings, or all findings have documented exceptions with justification.
  • No postinstall scripts download remote code, execute curl/wget, or modify paths outside the package directory.
  • No package names match known typosquatting patterns (one character off from a popular package).
  • Vulnerable transitive deps are addressed via overrides/resolutions where a direct upgrade cannot fix them.
  • CI pipeline uses npm ci / --frozen-lockfile / --immutable, not npm install.
  • .npmrc scopes any private registry to @org-scope/* only; no full-redirect to an untrusted registry.
  • All packages with known EOL runtime or framework status have a documented upgrade timeline.
  • package.json dependencies ranges are not * or >=0.0.0 for production packages.
  • Audit exceptions file exists with CVE ID, package, reason, reviewer, and date for each waived finding.
  • devDependencies are not require()-d in application code that ships to production.

Commands

# Detect package manager from lockfile
ls package-lock.json 2>/dev/null && echo "npm" || true
ls pnpm-lock.yaml    2>/dev/null && echo "pnpm" || true
ls yarn.lock         2>/dev/null && echo "yarn" || true
ls bun.lockb         2>/dev/null && echo "bun"  || true
ls poetry.lock       2>/dev/null && echo "poetry (python)" || true

# Non-destructive npm audit (capture JSON; do NOT run fix yet)
npm audit --json > /tmp/npm-audit.json 2>&1
cat /tmp/npm-audit.json | python3 -c "import json,sys; d=json.load(sys.stdin); print('critical:', d.get('metadata',{}).get('vulnerabilities',{}).get('critical',0), 'high:', d.get('metadata',{}).get('vulnerabilities',{}).get('high',0))"

# Python / pip
pip-audit --format json --output /tmp/pip-audit.json 2>/dev/null || echo "pip-audit not installed"

# Go
govulncheck ./... 2>/dev/null || echo "govulncheck not installed"

# Check lockfile version
node -e "const l=require('./package-lock.json'); console.log('lockfileVersion:', l.lockfileVersion)"

# Inspect all postinstall / prepare scripts in direct dependencies
node -e "
const pkg = require('./package.json');
const deps = {...(pkg.dependencies||{}), ...(pkg.devDependencies||{})};
Object.keys(deps).forEach(name => {
  try {
    const p = require('./node_modules/' + name + '/package.json');
    const s = p.scripts || {};
    const hooks = ['postinstall','preinstall','install','prepare'].filter(k => s[k]);
    if (hooks.length) console.log(name + '@' + p.version + ':', hooks.map(k => k + '=' + s[k]).join(' | '));
  } catch(e) {}
});
"

# Check for outdated packages (read-only)
npm outdated 2>/dev/null || true

# Check private registry config
cat .npmrc 2>/dev/null | grep -E "registry|scope" || echo "no .npmrc"

# Check whether CI uses npm ci or npm install
rg -n "npm install\b" .github/workflows/ .gitlab-ci.yml Makefile 2>/dev/null || true
rg -n "npm ci\b" .github/workflows/ .gitlab-ci.yml Makefile 2>/dev/null || true

# Check for wildcard or loose version ranges in production deps
node -e "
const pkg = require('./package.json');
Object.entries(pkg.dependencies||{}).forEach(([k,v]) => {
  if (v === '*' || v.startsWith('>=0') || v.startsWith('x')) console.log('LOOSE RANGE:', k, v);
});
"

# Check devDependencies used in production code (node_modules audit)
# List devDep names, then grep for require/import of those names in src/
node -e "const p=require('./package.json'); Object.keys(p.devDependencies||{}).slice(0,20).forEach(n=>console.log(n))" \
  | xargs -I{} sh -c 'rg -l "require.*{}\|from.*{}" src/ 2>/dev/null && echo "DEV IN PROD: {}" || true'
# Typosquatting quick check: compare package names against npm registry
# (manual step — check these with: npm view <suspected-package> time --json | head -5)
# Look for: very recent creation, <1000 weekly downloads, owner with no other packages

# Transitive CVE: identify the dependency chain for a specific package
npm ls <vulnerable-package> 2>/dev/null | head -20

# Check overrides/resolutions in package.json
node -e "const p=require('./package.json'); console.log(JSON.stringify(p.overrides||p.resolutions||{}, null,2))"

# Verify the lockfile is what was actually installed (hash check)
npm ci --dry-run 2>/dev/null | tail -5 || echo "dry-run not supported; run npm ci in CI only"

Severity rubric

SeverityExample
CriticalRemotely exploitable CVE (RCE, SQL injection) in a package reachable from a production request handler. Postinstall script downloads and executes arbitrary code. Confirmed typosquatting package installed.
HighXSS or path traversal CVE in a package handling untrusted user input. Lockfile deleted and regenerated without audit of version changes. npm install (not npm ci) used in CI, allowing lockfile drift.
MediumReDoS or DoS CVE in a package reachable from user input. Loose production version range (^1.0.0 is fine; >=1 <99 is not). devDependency found in production code. Outdated major version with known vulnerabilities in that major.
LowInformational CVE not reachable in this project's code paths, with a documented exception. Outdated minor version with no known vulnerability. Missing audit exception documentation for a known, assessed CVE.

Common issues & anti-patterns

  • Deleted and regenerated lockfile: dependency versions silently drift; every transitive version must be re-reviewed as if all packages were newly added.
  • npm install in CI: the lockfile can mutate between CI runs; always use npm ci. A failing npm ci is not a problem to paper over — it signals a real inconsistency between package.json and the lockfile.
  • Unpinned devDependencies promoted to production: a require() in application code that pulls a dev-only package will silently fail in a production Docker image built from npm ci --omit=dev.
  • --legacy-peer-deps flag in CI: this flag silently installs incorrect peer versions. Its presence signals an outdated dependency graph that needs resolution, not suppression.
  • Scoped package namespace confusion: if your org namespace @acme is not claimed on the public registry, an attacker can publish @acme/internal-lib publicly with a higher version and npm will prefer it (dependency confusion attack).
  • Binary download postinstall without checksum verification: puppeteer, cypress, esbuild, and similar packages download platform binaries at install time. Verify the download script checks a hash against a bundled manifest — unchecked binary downloads are a supply chain risk.
  • Audit false negatives from bundling: npm audit inspects node_modules, but if a vulnerable package is bundled into a client-side chunk via webpack/rollup and then dropped from node_modules (e.g., via tree-shaking), audit may not flag it. Check the final bundle's included packages separately.
  • Exception file without dates: a "not exploitable" exception from 18 months ago may no longer be valid if the package's usage has changed. All exceptions must have a review date and a re-review interval.

Required output

## Dependency Supply Chain Review

### Critical CVEs requiring immediate fix
| Package | Installed | Safe version | CVE | Exploitable in this project |
|---------|-----------|-------------|-----|----------------------------|

### High CVEs — fix before next release
| Package | Installed | Safe version | CVE | Notes |

### Suspicious install-time scripts
- package@version: script content summary, risk level, recommendation.

### Outdated packages (1+ major behind)
| Package | Current | Latest | EOL? | Upgrade priority |
|---------|---------|--------|------|-----------------|

### Lockfile status
- Present: yes/no. Generator: npm/yarn/pnpm. Version: X. CI uses reproducible install: yes/no.

### Private registry config
- .npmrc present: yes/no. Scoped to org namespace only: yes/no. Risk: none/low/high.

### Audit exceptions (assessed not exploitable)
| CVE | Package | Reason | Reviewer | Date |

### Recommended next commands
1. npm audit fix  # review diff before committing — run npm audit again after to confirm
2. ...

### Summary
- Total direct dependencies: N. Total audit findings: N (critical: N, high: N).
- Single highest-priority action: one sentence.

Safety

  • Run npm audit --json (read-only) only. Do not run npm audit fix --force, npm install, or any script that modifies node_modules or the lockfile without explicit user approval.
  • Do not print package registry tokens or .npmrc auth values.
  • Do not run postinstall scripts or execute any downloaded binary as part of the review.
  • Do not approve or merge a PR that adds a package with an unreviewed postinstall script — surface it as a finding first.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.