fix(dashboard): keep the provider registry out of node:net (#11122) - #11154
Conversation
CI triage: all 5 red checks are inherited from the base — none originate hereVerified against a clean worktree at the base this PR was cut from (
Docs Gates
Fast Quality GatesAll three are present on #11146 as well; Unit shardsAll 17 CI-failing files were re-run at Two files that failed in a local full-suite run but not in CI were also cleared: What this PR does to the suiteFrom the shard logs on this PR's own run: Net effect is one fewer failure than the base, and no new ones. Worth a separate lookTwo of the above look like fresh base-reds not captured in the (empty) failure block of #9985: the migration-count drift from #11103, and the Note that |
…apw#11122) Includes changelog fragment for diegosouzapw#11154.
a90d003 to
3d4546e
Compare
2edb7a1
into
diegosouzapw:release/v3.8.50
…apw#11122) (diegosouzapw#11154) Validated on a worktree over the current tip: the red it fixes reproduced exactly as described (media-page-client-browser-bundle red since diegosouzapw#11122 — providerRegistry became reachable from the dashboard client bundle via node:net). Post-fix: bundle test 2/2 green, new ip-parity suite + is-local-provider 7/7, all 7 outboundUrlGuard consumer suites 76/76 (the moved normalizeHost/isPrivateHost keep their re-exports; routing behavior untouched). Thank you @yourspraveen — clean surgical extraction with a pure-JS ipVersion mirroring Node's own regexes.
Problem
#11122 pointed
isLocalProvider()atisPrivateHost(), imported fromsrc/shared/network/outboundUrlGuard.ts. That module's first line is:open-sse/config/providerRegistry.tsis reachable fromProviderDetailPageClient.tsx, so the dashboard's client bundle can no longer resolvenode:net.tests/unit/media-page-client-browser-bundle.test.tshas been red onrelease/v3.8.50since that merge — reproduced on the current tip (367ae2fb9):Fix
The routing behaviour from #11122 is correct and is left exactly as merged —
isLocalProvider()is untouched. Only the import path moves.normalizeHost()/isPrivateHost()move into a new, platform-freesrc/shared/network/privateHost.ts.isIPis swapped foripVersion(), a pure-JS equivalent built from the regexes Node itself uses inlib/internal/net.js.outboundUrlGuard.tsre-exportsisPrivateHost, so its ~10 existing callers are unchanged.providerRegistryimports the narrow module directly, so a futurenode:import in the guard cannot re-break the bundle.The diff to
providerRegistry.tsis one import line.Why the parity test matters
Replacing
isIPis security-critical: a narrower matcher would classify a private address as public and open the very egress the SSRF guard exists to close.tests/unit/private-host-ip-parity-11122.test.tstherefore assertsipVersionagainstnode:net#isIPverdict-for-verdict, not just spot behaviour:fe80::1%eth0)010.1.1.1), out-of-range octets,2001:db8::1::2AGENTS.md→ Regex Security)privateHost.tsfor the browser, pinning the invariant at the moduleprivateHost.tsalso inherits the #7682 rule from its parent — no@/-aliased import — so the packaged CLI keeps loadingoutboundUrlGuardwithout atsconfig.Verification
media-page-client-browser-bundle.test.ts367ae2fb9→ greenis-local-provider-11091.test.ts(from #11122)typecheck:core,eslint,check:cycles