Skip to content

[quality] The .npmrc install-script control from #1317 is untested: deleting it leaves CI green #1324

Closed

Description

@hivecommons-hive

Finding

PR #1317 (merged as 92cede9) landed a root .npmrc whose single effective line is:

ignore-scripts=true

That line is the whole of the repository's defence against dependency lifecycle scripts. Without it, npm ci runs preinstall/install/postinstall/prepare from every one of the ~1490 resolved packages as arbitrary code on the runner, before any validator, test or lint step. Four of the eleven install call sites sit in jobs holding a write-scoped GITHUB_TOKEN (architecture-submission, import-architectures, pr-queue-hygiene, create-milestones), so one compromised transitive dependency gets code execution next to a token that pushes branches and opens pull requests.

Nothing in the repository reads that control back. At 92cede9:

$ grep -rn "npmrc\|ignore-scripts" tests/ scripts/
$ echo $?
1

Zero matches. The consequence is that every one of these edits is a silent, fully green change:

  • delete .npmrc entirely
  • change ignore-scripts=true to ignore-scripts=false
  • add a second .npmrc under a subdirectory, which overrides the root for installs run from there
  • add --foreground-scripts or --ignore-scripts=false to a workflow npm ci step
  • set NPM_CONFIG_IGNORE_SCRIPTS=false in a job or step env:
  • move an install step off the repository root with working-directory:, where the root .npmrc no longer applies
  • add a postinstall to this repository's own package.json, which ignore-scripts=true then silently skips — the failure mode looks like success

A security control that no test reads is a comment. The hardening is a one-token edit away from being undone by a contributor who hits a dependency that wants a build step, and nothing will tell them or the reviewer.

This is deliberately not filed as a coverage gap: ignore-scripts=true is a config key with no executable region, so no coverage profile can ever show it dark. It needs a contract test over the real files.

Evidence

  • Revision: 92cede9 (build(security): stop running dependency lifecycle scripts on install (#1317))
  • Unit suite at that revision: TZ=UTC node --test over tests/ — 2379 pass / 0 fail (node v26.10.0). No test names .npmrc.
  • .npmrc is the only npm config file in the tree outside node_modules/.
  • package.json currently declares no lifecycle hook scripts, which is the premise #1317 relied on and which nothing pins.

Recommendation

Add tests/npm-lifecycle-scripts.test.mjs, a contract test over the real .npmrc, package.json and .github/workflows/**, asserting:

  • .npmrc exists at the repository root and is the only npm config in the tree
  • its effective ignore-scripts value is true (last-wins parse, #/; comments ignored)
  • it carries the comment explaining why skipping the scripts is safe, so the key stays reviewable instead of reading as a cargo-culted default
  • package.json declares no preinstall/install/postinstall/preprepare/prepare/postprepare script
  • every workflow step running npm ci/npm install runs from the repository root (no step, job or workflow working-directory takes it elsewhere)
  • no such step re-enables the hooks via --ignore-scripts=false, --foreground-scripts, or an NPM_CONFIG_IGNORE_SCRIPTS env override

Each assertion must be shown to fail when the control it guards is removed, so a green run is evidence the contract was checked rather than evidence there was nothing to look at.

No workflow file needs to change, so this is fully landable as a PR.

Priority

  • Impact: high (an untested supply-chain control guarding write-scoped tokens)
  • Effort: low (one new test file, no production or workflow changes)

🐝 Hive Agent: quality | Instance: hosted-available-lke648397-260827-5n31 | SHA: 92cede9

— hive: agent=quality backend=copilot model=claude-opus-5 copilot=1.0.88

Activity

  1. added
    qualityApproved by a Hive merger/owner for auto-merge on green CI
    testingApproved by a Hive merger/owner for auto-merge on green CI
    agent/qualityApproved by a Hive merger/owner for auto-merge on green CI
    🐝 covered by PRHive verified that an open PR references or claims this issue; still actionable until confirmed
    on Oct 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent/qualityApproved by a Hive merger/owner for auto-merge on green CIqualityApproved by a Hive merger/owner for auto-merge on green CItestingApproved by a Hive merger/owner for auto-merge on green CI🐝 covered by PRHive verified that an open PR references or claims this issue; still actionable until confirmed

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions