feat(mcp-scan): apply npx dependency overrides during the security scan - #831
Merged
Conversation
Contributor
🔒 MCP Security Scan Results✅ onchain-mcp
Summary: Scanned 1 MCP server(s), all passed security checks. ✅ |
Contributor
Author
|
CI came out as expected.
The 10 remaining |
stack merge was automatically disabled
August 5, 2026 18:43
Pull Request is not mergeable
stack merge was automatically disabled
August 5, 2026 18:44
Pull Request is not mergeable
The scan runs the package directly rather than the built image, so it did not see spec.overrides and exercised a different dependency tree than the one that ships. uvx constraints were already reapplied; npx overrides were skipped with a note, because npm honors "overrides" only from a package.json it installs into and the scan has no project directory. Stage a throwaway project containing the server package plus the overrides block, npm install it, and run the scanner with that directory as its working directory so npx resolves the installed tree. Pass npx --no-install as well, so npx fails loudly instead of silently fetching an un-overridden copy of the package. Beyond matching what ships, this makes the scan a check on the override itself: one that breaks the server's startup now fails the scan before the image is published rather than producing a broken container. Measured cost is roughly 3 seconds of npm install, paid only by servers that declare overrides.
@bankless/onchain-mcp exact-pins the SDK at 1.7.0, which carries two high advisories that fail the build-containers Grype gate. Neither fix is reachable without overriding the pin. Picked 1.26.0 rather than the minimum 1.25.2: GHSA-345p-7cg4-v4c7 affects >=1.10.0,<=1.25.3, which 1.7.0 predates, so the smaller bump would have traded two advisories for a third. Verified: grype --fail-on high --only-fixed reports no high or critical findings on the built image, and the server still enumerates all 10 tools in the security scan. This is also the first npx spec to carry overrides, so it exercises the scan path added in the previous commit. Refs #830
The npm staging happens before the scanner's own try/finally, so a failure there escaped as an uncaught traceback and left the temp project behind. A runner without npm on PATH produced a raw FileNotFoundError, and an install that hit the 300s timeout would have done the same. Pre-check for npm and for the package fields, and clean up the temp project on any staging failure.
danbarr
force-pushed
the
feat/mcp-scan-npm-overrides
branch
from
August 5, 2026 18:49
c398bee to
d52fef2
Compare
samuv
approved these changes
Aug 5, 2026
This was referenced Aug 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #669. Addresses the npx half of @samuv's P1 review comment, which I had deferred there.
What
The scan runs the package directly rather than the built image, so it never saw
spec.overridesand exercised a different dependency tree than the one that ships. #669 fixed this for uvxconstraints; npxoverrideswere skipped with a logged note, because npm honorsoverridesonly from apackage.jsonit installs into and the scan has no project directory.This stages a throwaway project containing the server package plus the
overridesblock, runsnpm installin it, and runs the scanner with that directory as its working directory sonpxresolves the installed tree. It also passesnpx --no-install, which is load-bearing: without it npx may silently fetch an un-overridden copy and quietly void the whole thing.Why I changed my mind on deferring
My deferral argument in #669 was that these overrides swap a vulnerable but working dependency for a patched one, so they change neither startup nor the tool surface. That holds for a correct override. It does not hold for a mistaken one.
While prototyping, a deliberately crude
zodoverride broke context7's startup outright (ERR_PACKAGE_PATH_NOT_EXPORTED). So applying overrides in the scan makes it a check on the override itself: a startup-breaking override now fails the scan before the image publishes, instead of shipping a broken container. That is a better reason to do this than the vulnerability-parity argument, and it is the one I would not have found without building it.Cost
Roughly 3 seconds of
npm install, paid only by servers that declare overrides. Measured 3.0s for context7, 5.4s end to end for onchain-mcp including the scan.Scope caveat worth recording
12 of 30 npx servers carry
security.insecure_ignore: truebecause they need real credentials to start, andprocess_scan_results.pytreats empty scan output as a warning and proceeds. For those, overrides have no observable effect on the scan no matter what we do here. That set includesbrightdata-mcp, which is the #469 case #668 was opened for, plusmcp-server-neon,mcp-jetbrains, andbrowserbase-mcp-server.So this is genuinely useful for scannable servers, and inert for the ones that need tokens. Documented in
docs/adding-servers.mdso the next person does not have to rediscover it.Second commit
onchain-mcpis the first npx spec to carryoverrides, which means CI actually exercises the new path rather than repeating #669's situation where the mechanism shipped with no spec using it.It also fixes a real failure from #830:
@bankless/onchain-mcpexact-pins the SDK at 1.7.0, carrying two high advisories with no reachable fix. I picked 1.26.0 over the minimum 1.25.2 because GHSA-345p-7cg4-v4c7 affects>=1.10.0,<=1.25.3, which 1.7.0 predates, so the smaller bump would have traded two advisories for a third.Verification
npm installstaging applies the override: SDK resolves to 1.26.0 from a pinned 1.7.0.grype --fail-on high --only-fixedon the built image: no high or critical findings, exit 0.constraintspath unchanged, and specs without overrides produce byte-identical scan config.🤖 Generated with Claude Code