Skip to content

fix(arborist): allow-remote exemption for proxy/mirror-fronted registry tarballs#9550

Open
manzoorwanijk wants to merge 1 commit into
npm:latestfrom
manzoorwanijk:fix/allow-remote-registry-proxy-origin-9548
Open

fix(arborist): allow-remote exemption for proxy/mirror-fronted registry tarballs#9550
manzoorwanijk wants to merge 1 commit into
npm:latestfrom
manzoorwanijk:fix/allow-remote-registry-proxy-origin-9548

Conversation

@manzoorwanijk

Copy link
Copy Markdown
Contributor

With allow-remote=none (the default on npm 12) or allow-remote=root, a npm install fails with EALLOWREMOTE on ordinary registry dependencies when the configured registry origin differs from the lockfile resolved origin.

npm error code EALLOWREMOTE
npm error Fetching packages of type "remote" have been disabled

This is the common proxy/mirror case: a committed package-lock.json whose resolved URLs point to https://registry.npmjs.org/..., while the machine (or CI) is configured to use a private registry proxy/mirror with a different origin.
It affects both the hoisted and the linked install strategy.

Why

When extracting a registry-resolved package, reify hands pacote a name@URL spec, which pacote re-parses as type=remote and gates with allow-remote.
To avoid mis-firing on registry tarballs, #isRegistryResolvedTarball exempts them — but it compared the raw lockfile resolved URL against the configured registry origin.
With a proxy/mirror configured, resolved is the canonical registry.npmjs.org URL while the configured registry is the proxy, so the origins never matched, the exemption returned false, and the registry tarball was rejected as remote.

Crucially, reify already fetches a different URL than the raw resolved: #registryResolved applies replace-registry-host (default npmjs), rewriting the registry.npmjs.org host to the configured registry while preserving the path.
So npm fetches the tarball from the proxy correctly; only the allow-remote check was evaluating the wrong (pre-rewrite) URL.

How

Evaluate the effective URL npm actually fetches, not the raw lockfile value.

#isRegistryResolvedTarball now parses this.#registryResolved(node.resolved) — the host-rewritten URL — before the same origin + registry-path-prefix comparison.
After rewriting, a public-registry-pinned tarball resolves to the configured registry and is correctly recognized as registry-mediated.

The existing security boundary is preserved: under the default replace-registry-host, a same-origin tarball pointing outside the registry path is not rewritten and is still rejected, and a genuinely URL-declared dependency still fails the node.isRegistryDependency guard.
Under replace-registry-host=always, every tarball is routed through the configured registry, so registry dependencies are no longer treated as remote — consistent with what always means.

References

Fixes #9548

@manzoorwanijk manzoorwanijk marked this pull request as ready for review June 13, 2026 09:22
@manzoorwanijk manzoorwanijk requested review from a team as code owners June 13, 2026 09:22
@manzoorwanijk

Copy link
Copy Markdown
Contributor Author

@owlstronaut @JamieMagee this change might require some careful review.

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.

[BUG] Registry-tarball allow-remote exemption fails when the configured registry origin differs from the lockfile resolved origin (proxy/mirror)

1 participant