Without a committed lock file, every deployment resolves dependency versions fresh from the registry. A package that satisfies ^1.2.3 today might resolve to 1.9.0 tomorrow after the maintainer pushes a new version — and if that version contains malicious code (as happened with ua-parser-js, colors, and event-stream), your production deployment installs it silently. OWASP A08 (Software and Data Integrity Failures) covers this class of dependency confusion. SLSA Level 1 requires pinned dependency declarations; SSDF PW.4.4 requires reproducible builds. CWE-829 (Inclusion of Functionality from Untrusted Control Sphere) maps to the scenario where a registry compromise affects your build.
Medium because missing lock files allow dependency version drift between deploys, creating a window for supply chain attacks during any deployment that resolves newer package versions.
Generate a lock file with your package manager and commit it to the repository. Never add lock files to .gitignore.
# Generate (use whichever matches your package manager)
npm install # creates package-lock.json
pnpm install # creates pnpm-lock.yaml
yarn install # creates yarn.lock
bun install # creates bun.lockb
Commit the lock file: git add package-lock.json && git commit -m 'chore: add lock file'. In CI, use npm ci instead of npm install — ci enforces the lock file and fails if it's out of sync with package.json.
ID: security-headers.basic-hygiene.lockfile-present
Severity: medium
What to look for: Count all lock files present in the project root: package-lock.json, pnpm-lock.yaml, yarn.lock, or bun.lockb. Verify the found lock file is not in .gitignore.
Pass criteria: Exactly 1 lock file appropriate for the detected package manager is present in the project root (package-lock.json for npm, pnpm-lock.yaml for pnpm, yarn.lock for Yarn, bun.lockb for Bun) and the lock file is not listed in .gitignore. No more than 1 lock file should be present — multiple lock files from different package managers indicate a misconfiguration.
Fail criteria: No lock file found, or the lock file is listed in .gitignore.
Skip (N/A) when: The project uses no package manager (e.g., static HTML-only project, or a Go/Rust project with its own dependency mechanism).
Detail on fail: "No package-lock.json, pnpm-lock.yaml, or yarn.lock found in project root" or "yarn.lock is listed in .gitignore — lock file is not committed"
Remediation: Lock files ensure that every deployment uses exactly the same dependency versions, preventing supply chain attacks where a malicious version could be installed:
# Generate lock file (use your package manager)
npm install # creates package-lock.json
pnpm install # creates pnpm-lock.yaml
yarn install # creates yarn.lock
Then ensure it's not in .gitignore and commit it.