Without a committed lock file, dependency resolution is non-deterministic — npm install on different machines or at different times may pull different transitive dependency versions. CWE-1357 (Reliance on Insufficiently Trustworthy Component) and OWASP A06 (Vulnerable and Outdated Components) both flag unpinned dependencies. SLSA L2 and SSDF PW.4 require reproducible builds with verified dependency integrity. A supply-chain attack can introduce a malicious version of a widely-used package; without a lock file, your CI might silently install the compromised version the day it is published.
Low because unlocked dependencies primarily create supply-chain risk during installation rather than runtime, but they open a window for silent malicious version substitution on every install.
Commit the lock file and switch CI from npm install to npm ci:
# Verify the lock file is not gitignored
grep 'package-lock' .gitignore # Should return nothing
# Commit the lock file
git add package-lock.json
git commit -m 'Add package-lock.json'
In your CI pipeline (/.github/workflows/ci.yml):
- name: Install dependencies
run: npm ci # Installs exactly from lock file; fails if out of sync
npm ci is faster than npm install on CI because it skips the dependency resolution step.
ID: security-hardening.dependency-security.lock-files
Severity: low
What to look for: Count all package managers in use and verify each has a corresponding lock file. check that a lock file exists (package-lock.json, yarn.lock, or pnpm-lock.yaml) and is committed to the repository. Verify that CI/CD uses the lock file (e.g., npm ci not npm install).
Pass criteria: A lock file is committed to the repository. CI/CD installs using the lock file (npm ci, yarn install --frozen-lockfile, pnpm install --frozen-lockfile) — 100% of package managers must have lock files committed to version control. Report: "X package managers found, all Y have committed lock files."
Fail criteria: No lock file committed. Lock file is listed in .gitignore. CI/CD runs npm install in a way that may update the lock file.
Skip (N/A) when: Never — all projects with npm/yarn/pnpm dependencies should have a lock file.
Detail on fail: "package-lock.json not found in repository root — dependency versions not pinned" or "yarn.lock listed in .gitignore — lock file not committed to version control"
Remediation: Commit your lock file and use npm ci in CI/CD:
# Ensure lock file is not in .gitignore
grep "package-lock.json" .gitignore # Should return nothing
# In CI/CD pipeline, use npm ci instead of npm install
npm ci # Installs from lock file, fails if lock file is out of sync
For new projects, npm install creates package-lock.json. Commit it:
git add package-lock.json
git commit -m "Add package-lock.json"