Skip to content

JSLEEKR/lockcheck

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

lockcheck

Lockfile integrity analyzer for supply chain security

Build Tests License TypeScript Node


Why This Exists

npm audit and Snyk find CVEs. Nobody checks if your lockfile itself is healthy.

Lockfiles are the foundation of reproducible builds, yet they accumulate structural problems that vulnerability scanners completely ignore:

  • Phantom dependencies -- packages in your lockfile that no manifest dependency requires. Leftover from removed packages, they bloat installs and expand your attack surface.
  • Manifest drift -- your lockfile resolves versions outside the ranges declared in package.json. This means npm install and npm ci produce different results.
  • Duplicate resolutions -- the same package resolved to 3+ versions. Bundle size bloat, subtle bugs from multiple instances of the same library.
  • Missing integrity hashes -- packages without SRI hashes can be silently replaced by a compromised registry.
  • Registry anomalies -- dependencies resolved from unexpected registries. A classic supply chain attack vector.
  • Install scripts in transitive deps -- postinstall scripts in deep dependencies are how most supply chain attacks execute.

lockcheck catches all of these across npm, yarn (classic + berry), pnpm, poetry, and Go modules.

Quick Start

# Install
npm install -g lockcheck

# Run in any project directory
lockcheck check

# Strict mode (warnings = errors)
lockcheck check --strict

# JSON output for CI
lockcheck check --format json

# SARIF output for GitHub Security tab
lockcheck check --format sarif

# Compare two lockfiles
lockcheck diff package-lock-old.json package-lock-new.json

# Lockfile statistics
lockcheck stats

What It Checks

Check Severity Description
phantom-dependency warning Package in lockfile not traceable to any manifest dependency
manifest-drift error Lockfile version outside manifest's declared semver range
duplicate-resolution info/warning Same package resolved to multiple versions
missing-integrity warning/error Missing or malformed integrity hash
registry-anomaly warning Package resolved from untrusted registry
install-script info/warning Package has install scripts (higher severity for transitive deps)

Supported Ecosystems

Lockfile Manifest Ecosystem
package-lock.json (v1/v2/v3) package.json npm
yarn.lock (classic) package.json Yarn 1.x
yarn.lock (berry) package.json Yarn 2+
pnpm-lock.yaml package.json pnpm
poetry.lock pyproject.toml Python Poetry
go.sum go.mod Go Modules

CLI Reference

lockcheck check

Options:
  -l, --lockfile <path>              Path to lockfile (auto-detect if not specified)
  -s, --strict                       Strict mode - warnings become errors
  -f, --format <format>              Output format: text, json, sarif (default: text)
  --skip-checks <checks>             Comma-separated checks to skip
  --ignore-packages <packages>       Comma-separated packages to ignore
  --trusted-registries <registries>  Comma-separated trusted registries

lockcheck diff <old> <new>

Compare two lockfiles and show added, removed, and changed packages.

Options:
  -f, --format <format>  Output format: text, json (default: text)

lockcheck stats

Show lockfile statistics: package count, integrity coverage, duplicates, etc.

Options:
  -l, --lockfile <path>  Path to lockfile (auto-detect if not specified)
  -f, --format <format>  Output format: text, json (default: text)

Exit Codes

Code Meaning
0 Clean -- no errors or warnings
1 Errors found (or warnings in strict mode)
2 Warnings found (non-strict mode)

Configuration

Create .lockcheckrc or .lockcheckrc.json in your project root:

{
  "strict": false,
  "format": "text",
  "skipChecks": ["install-script"],
  "ignorePackages": ["fsevents"],
  "trustedRegistries": ["registry.npmjs.org", "npm.pkg.github.com"]
}

CI Integration

GitHub Actions

- name: Check lockfile integrity
  run: npx lockcheck check --strict --format sarif > lockcheck.sarif

- name: Upload SARIF
  uses: github/codeql-action/upload-sarif@v3
  with:
    sarif_file: lockcheck.sarif

Pre-commit Hook

# .husky/pre-commit
npx lockcheck check --strict

Programmatic API

import { Analyzer, detectParser, getManifestFilename } from 'lockcheck';
import * as fs from 'fs';

// Parse lockfile
const lockContent = fs.readFileSync('package-lock.json', 'utf-8');
const parser = detectParser(lockContent, 'package-lock.json');
const lockfile = parser.parseLockfile(lockContent);

// Parse manifest
const manifestContent = fs.readFileSync('package.json', 'utf-8');
const manifest = parser.parseManifest(manifestContent);

// Analyze
const analyzer = new Analyzer();
const report = analyzer.analyze(lockfile, manifest, 'package-lock.json', {
  strict: true,
  ignorePackages: ['fsevents'],
});

console.log(`Risk score: ${report.summary.riskScore}/100`);
console.log(`Errors: ${report.summary.errors}`);
console.log(`Warnings: ${report.summary.warnings}`);

// Diff two lockfiles
const oldLock = parser.parseLockfile(fs.readFileSync('old.lock', 'utf-8'));
const newLock = parser.parseLockfile(fs.readFileSync('new.lock', 'utf-8'));
const diff = analyzer.diff(oldLock, newLock);

// Stats
const stats = analyzer.stats(lockfile);

Example Output

lockcheck analysis report
==================================================
Lockfile: package-lock.json
Format:   npm
Packages: 847
Risk:     35/100

Found: 2 error(s), 5 warning(s), 3 info(s)

[manifest-drift]
  [x] ERROR: Package "lodash" locked at 3.10.1 but manifest requires ^4.17.0
  [x] ERROR: Package "debug" is declared in manifest but missing from lockfile

[phantom-dependency]
  [!] WARN: Package "leftpad" is in lockfile but not traceable to any manifest dependency
  [!] WARN: Package "event-stream" is in lockfile but not traceable to any manifest dependency

[registry-anomaly]
  [!] WARN: Package "malicious-pkg@1.0.0" is resolved from untrusted registry: evil-npm.io

[duplicate-resolution]
  [-] INFO: Package "debug" is resolved to 3 different versions: 2.6.9, 3.2.7, 4.3.4

[install-script]
  [!] WARN: Transitive dependency "esbuild@0.19.0" has install scripts
  [!] WARN: Transitive dependency "sharp@0.33.0" has install scripts

==================================================
RESULT: FAIL

How It Differs From Existing Tools

Feature npm audit Snyk socket.dev lockcheck
CVE detection Yes Yes Yes No
Phantom dependencies No No No Yes
Lockfile-manifest drift No No No Yes
Duplicate resolution No No Partial Yes
Integrity hash check No No No Yes
Multi-ecosystem npm only Multi Multi Multi
Offline capable No No No Yes
SARIF output No Yes No Yes
Zero config Yes No No Yes

lockcheck complements vulnerability scanners. Run npm audit for CVEs, run lockcheck for structural integrity.

Architecture

src/
  cli/              # CLI entry point and commands
  core/
    analyzer.ts     # Analysis orchestrator
    scoring.ts      # Risk scoring engine
    checks/         # Individual check modules
  parsers/          # Lockfile format parsers (npm, yarn, pnpm, poetry, go)
  formatters/       # Output formatters (text, JSON, SARIF)
  config/           # Configuration loader
  utils/            # Semver and hash utilities

License

MIT

About

Lockfile integrity analyzer - detect phantom deps, manifest drift, duplicates, and supply chain risks across npm, yarn, pnpm, poetry, and Go

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors