Skip to content

security(npm): harden npm and update project deps#710

Closed
pfarikrispy wants to merge 5 commits into
OWASP:mainfrom
pfarikrispy:main
Closed

security(npm): harden npm and update project deps#710
pfarikrispy wants to merge 5 commits into
OWASP:mainfrom
pfarikrispy:main

Conversation

@pfarikrispy

Copy link
Copy Markdown

Summary

npm ecosystem has become pretty vuln to malware through supply chain attacks. This PR adds a .npmrc that addresses that explicitly. Security best practices from an npm security community project where followed. Afterwards, deps were updated, attestations verified and a vuln in better-sqlite addressed by downgrading to 12.10.x, while we wait for upstream.

Why this change

Without the "back-off period" for newer packages, the pkg mgr will pull in any and all updates as soon as available. Waiting for 3-5 days gives the community time to test, scan and prepare fixes when. supply chain attacks are detected.

What changed

  1. Created a new .npmrc file with:
  • ignore-scripts=true: Disables arbitrary package lifecycle scripts during installations to block malicious post-install code execution.
  • allow-git=none: Disallows git dependencies (which bypass security audits and registries).
  • min-release-age=5: Enforces a 5-day release cooldown for dependencies.
  1. Modified package.json:
  • Upgraded "jest" from ^25.0.0 to ^29.7.0 to restore compatibility with Node 24+.
  • Added "lint:lockfile" script to validate that dependencies originate from the trusted npm registry via HTTPS.
  • Added "overrides" configuration for "js-yaml": "^4.2.0" to resolve a denial of service vulnerability (GHSA-h67p-54hq-rp68) in transitive dependencies.
  • Ran npm update and npm install across both the root project and the website subproject to update package versions and regenerate lockfiles.

Validation

  1. Successfully validated the root lockfile via:
$ npm run lint:lockfile
 ✔ No issues detected
  1. Ran the Jest test suite at the root directory:
Result: All 512 unit/integration tests passed successfully under Jest v29.7.0 and Node 24.

Test Suites: 37 passed, 37 total
Tests:       512 passed, 512 total
Snapshots:   0 total
Time:        2.137 s
  1. Verified that TypeScript compiles without error:
$ npm run build
(Completed with exit code 0)
  1. Ran a check of the project's direct dependencies using npx npq:

better-sqlite3@12.10.1: Flagged as a supply chain script warning (due to compiling native bindings on install) and a publication date of 6 days ago (which passes our 5-day project-level cooldown limit, though still flagged as recent by npq's default check).
Other Packages: Several packages were noted for missing provenance attestations or showing dormancy before their latest release. However, all dependencies are standard packages from the official registry.npmjs.org.

User-facing impact

Does not change any user-facing actions, only deps:

  • affect scanning behavior
  • affect output formatting
  • affect JSON output
  • affect docs only

Notes

I HIGHLY recommend adding a new CI job to test deps using npm npq, just like I did here before making a PR. It surfaced some last minute issues that were resolved ina. few minutes.

Comment on lines +784 to +788
const child = spawn(cmd, args, {
stdio: "ignore",
detached: true,
shell: false,
});
@sonukapoor

Copy link
Copy Markdown
Collaborator

Hi @pfarikrispy - thanks for the thoughtful security focus here, and for the follow-up commit. A few things I'd like you to scope down before this can merge:

  1. Remove the .trunk/ directory and all Trunk-related changes - we have an open issue for linting tooling (chore: add Prettier for consistent code formatting #446) with a specific approach planned. Bundling a new linter setup into an unrelated PR makes it hard to review and maintain independently.

  2. Remove ignore-scripts=true from .npmrc (and the npm rebuild better-sqlite3 CI steps it introduced) - better-sqlite3 compiles native bindings on install, so ignore-scripts=true would also break npm install for anyone cloning the repo locally, not just CI. min-release-age=5 and allow-git=none are worth keeping.

  3. Remove the overrides entry for js-yaml - we use .cve-lite/baseline.json to track accepted transitive vulnerabilities rather than npm overrides.

  4. Remove the lint:lockfile script - scanning lockfiles for vulnerabilities is what CVE Lite CLI itself does.

  5. Remove the workflow SHA pinning changes - there's already an open PR (security(ci): pin GHA using immutable digests instead of mutable versions #705) covering this. The format in this PR also appears to append the old ref to the comment rather than replace it, which would break CI parsing.

  6. Remove the CHANGELOG.md edits - the changelog is maintained by the project team at release time.

  7. Remove any README changes not directly tied to the .npmrc addition.

Once scoped down to just the .npmrc (min-release-age and allow-git=none), happy to move this forward quickly.

@pfarikrispy

Copy link
Copy Markdown
Author

Yes I saw the giant trunk changes after the PR was created, I forgot they were in there.

Won't it be much easier and cleaner to just close/delete this PR and create a new one for just the .npmrc?

@sonukapoor

Copy link
Copy Markdown
Collaborator

Yes I saw the giant trunk changes after the PR was created, I forgot they were in there.

Won't it be much easier and cleaner to just close/delete this PR and create a new one for just the .npmrc?

Yes, I agree @pfarikrispy

@pfarikrispy

pfarikrispy commented Jun 19, 2026 via email

Copy link
Copy Markdown
Author

@sonukapoor sonukapoor closed this Jun 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants