Skip to content

[APS-19734] fix: harden .npmrc with supply-chain security directives - #1128

Open
Rohannagariya1 wants to merge 3 commits into
masterfrom
fix/APS-19734-npmrc-hardening
Open

Rohannagariya1 wants to merge 3 commits into
masterfrom
fix/APS-19734-npmrc-hardening

Conversation

@Rohannagariya1

@Rohannagariya1 Rohannagariya1 commented Jun 11, 2026

Copy link
Copy Markdown
Collaborator

Security Fix: APS-19734 — .npmrc supply-chain hardening

Repo failed BrowserStack's weekly Enigma .npmrc audit (SC-12282). This PR adds the subset of the Supply Chain Security Enhancements tech spec that actually delivers value for a public CLI repo. The remaining directives from the tech spec were reviewed and dropped — reasoning at the bottom.

Actual diff — 3 lines added to .npmrc

min-release-age=7
strict-ssl=true
save-exact=true

Flags added — what each does and why

min-release-age=7

Only resolves package versions that were published ≥ 7 days ago during install.

Why: blocks freshly-published malicious versions (event-stream, ua-parser-js, Shai-Hulud-style attacks) before the community or npm registry can detect and yank them. A version published today that's malicious usually gets yanked within 24–72 hours; the 7-day window means we never install those versions in that danger period.

Scope: dev-time only — customers doing npm install browserstack-cypress-cli read their own .npmrc, not ours. Protects our supply chain from a freshly-published malicious transitive dep landing in our package-lock.json.

Compatibility: requires npm 11.10+. Older npm silently ignores the flag (no harm, just no protection).

strict-ssl=true

Enforces TLS certificate validation when npm connects to any HTTPS URL (npm registry, tarball downloads, etc.).

Why: true is npm's default, but a contributor on a corporate proxy or MITM'd network may have strict-ssl=false set in their ~/.npmrc as a workaround. That personal override silently accepts fake certs on all their npm installs — including when they clone this repo and run npm install. Setting strict-ssl=true at the project level sits above user-level config in npm's precedence order, so it overrides the personal override and forces cert validation on our repo's installs.

What could go wrong without it: contributor on compromised network → their ~/.npmrc accepts fake npmjs.org cert → malicious axios ships into our package-lock.json → we push that lockfile to master.

Scope: dev-time only, same as above. Zero effect on customer installs.

save-exact=true

When a contributor runs npm install <pkg>, npm writes the exact resolved version to package.json (e.g., "axios": "1.15.0") instead of a caret range ("^1.15.0").

Why: without this, npm install <pkg>@X.Y.Z writes ^X.Y.Z which allows silent upgrades to any 1.x.x on the next npm install. That silent upgrade path is how you get accidentally-bumped-to-vulnerable transitives without a code review. Exact versions force every version bump to be a deliberate act with a diff.

Flags NOT added — proposed by tech spec / earlier iteration, rejected on review

Applying the rule: if a flag has no concrete "here's what specifically breaks without it" justification, and might cause weird breakages, don't add it. Four flags fail that test in this repo:

ignore-scripts=true — rejected

  • The runtime path already blocks scripts explicitly: bin/helpers/packageInstaller.js:102, 105 calls spawn('npm', ['install', '--ignore-scripts', ...]) so the CLI's runtime deps-install on customer machines is already protected via cmdline flag. Doesn't rely on .npmrc.
  • Real footgun: packages with native builds (bcrypt, sharp, node-sass) use postinstall to compile their native binary. This flag silently skips the compile → install "succeeds" → runtime hits MODULE_NOT_FOUND or invalid ELF header with no obvious cause.
  • Dev-time supply chain risk is low — our deps are vetted, named packages.

audit-level=high — rejected

  • Our CI doesn't gate on npm audit (uses Semgrep, CodeQL, SCA scanner instead). Flag has no operational effect anywhere in the pipeline.
  • If a contributor runs npm audit locally, this flag hides medium/low CVEs from the report — slightly counterproductive.
  • If we ever decide to gate CI on npm audit, we should be explicit in the CI script (npm audit --audit-level=high), not hide the threshold in .npmrc.

legacy-peer-deps=false — rejected

  • Already the default in npm 7+. Adding it doesn't change behavior; it's noise.
  • npm install --legacy-peer-deps cmdline override for one-off cases still works regardless of this flag.

engine-strict=true — rejected

  • Only affects contributors (customer installs read customer's .npmrc).
  • Real footgun: contributor 0.0.1 off the pinned Node version can't even run npm install — install fails hard. For a repo with casual contributors, this is friction that produces no real security value.
  • The package.json engines field's npm WARN EBADENGINE message on install is usually enough signal.
  • No consistent BS-wide policy on this — adding it here creates a one-off convention.

Testing / Verification

  • CI green: CodeQL x3, semgrep/ci, Semgrep OSS, CodeRabbit.
  • min-release-age=7 verified with npm view <pkg> time on recent bumps — expected versions resolve; freshly-published versions get skipped as documented.
  • strict-ssl=true verified by temporarily setting strict-ssl=false in ~/.npmrc and running npm install in this repo — install correctly uses project-level true regardless.
  • save-exact=true verified by running npm install lodash@4.17.21 --dry-run — writes "lodash": "4.17.21" (no caret).

Jira Ticket

https://browserstack.atlassian.net/browse/APS-19734

- Add ignore-scripts, strict-ssl, save-exact, engine-strict,
  legacy-peer-deps=false, audit-level=high
- Preserve existing package-lock=true and lockfile-version=1
- Public repo: access=restricted intentionally omitted
- Validated: npm install + npm test identical before/after
  (678 passing, 13 pre-existing failures unchanged); no install
  scripts in the dep tree, so ignore-scripts=true causes no regression

Resolves: APS-19734

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Rohannagariya1

Copy link
Copy Markdown
Collaborator Author

Closing as not needed — synced with Shabbir (Security EM). The supply-chain .npmrc hardening flagged by the Enigma audit is not required for these repos; dropping per that decision.

@Rohannagariya1

Copy link
Copy Markdown
Collaborator Author

Reopening — closed in error. This repo is internal per Rohan; keeping the hardened .npmrc PR open. Only the open-source sample repos are being dropped (synced with Shabbir, Security EM).

@coderabbitai

coderabbitai Bot commented Sep 15, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited), Workspace UI (inherited)

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 933cfaff-cf7c-4418-af81-ccba33ebc715

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

Raghav11-11
Raghav11-11 previously approved these changes Sep 15, 2026
Raghav11-11
Raghav11-11 previously approved these changes Sep 16, 2026
Comment thread .npmrc Outdated
save-exact=true
engine-strict=true
legacy-peer-deps=false
audit-level=high

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove last 3

Comment thread .npmrc Outdated
min-release-age=7
package-lock=true
lockfile-version=1
ignore-scripts=true

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this also

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