Allow WebFinger discovery for localhost/private hosts by default - #1386
Merged
Conversation
webfinger.js v3 added an `allow_private_addresses` config option that
defaults to `false`, so `WebFinger#resolveAndValidateHost` started
throwing on any localhost / private-IP address before any HTTP request
went out. That broke `rs.connect("user@localhost:8000")` and any
self-hosted setup on a private LAN address since `2.0.0-beta.9`.
The SSRF guard makes sense for server-side webfinger callers, but
remoteStorage.js runs in browsers, where cross-origin requests are
already gated by the same-origin policy / CORS. The flag's threat
model doesn't apply there and only blocks legitimate localhost
development.
Add a `discoveryAllowPrivateAddresses` config option that defaults to
`true` (restoring the pre-beta.9 behaviour) and forwards to
webfinger.js. Non-browser embedders that want the SSRF guard back can
opt out via `new RemoteStorage({ discoveryAllowPrivateAddresses: false })`.
Add regression tests covering both paths and document the option in
the `RemoteStorage` constructor docs.
silverbucket
force-pushed
the
bugfix/1384-localhost_discovery
branch
from
April 27, 2026 19:45
8fed77b to
8b572e6
Compare
Updated comment for WebFinger discovery setting.
silverbucket
marked this pull request as ready for review
April 27, 2026 20:01
raucao
requested changes
Apr 28, 2026
Replace the flat `discoveryAllowPrivateAddresses` and `discoveryTimeout`
config keys with a nested `discovery` group, so callers can write
`{ discovery: { timeout: 1000 } }` (or `{ discovery: { allowPrivateAddresses: false } }`)
without the keys ballooning further as the discovery feature grows.
The `RemoteStorage` constructor now merges the `discovery` sub-object
key by key against the defaults, so a partial override does not
clobber the unspecified subkeys (mirroring how `changeEvents`'
all-or-nothing behaviour was the main wart of the previous shape).
This is a breaking change for direct readers of `config.discoveryTimeout`
/ `config.discoveryAllowPrivateAddresses`, but those keys only ever
shipped in `2.0.0-beta.x`, so the rename is safe.
Co-authored-by: Doug Reeder <reeder.29@gmail.com>
DougReeder
reviewed
Apr 30, 2026
raucao
requested changes
May 19, 2026
raucao
left a comment
Member
There was a problem hiding this comment.
Looking great! 👏
The PR description needs to mention the breaking change for the existing discovery timeout config key. At the moment, it only describes the fix.
Member
Author
|
@raucao updated! |
Fixes class doc layout and makes the hint more prominent where it's actually needed.
Member
|
I moved the documentation to a a more appropriate place, which fixes the issue and also makes it more prominent/relevant where it's needed: 7129411 I also added a drive-by commit improving some wording on the same page. |
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.

Problem
rs.connect("user@localhost:8000")(and any address whose host resolves to a localhost / private IP) fails immediately withWebFingerError: private or internal addresses are not allowed, before any HTTP request is made.This is a regression introduced by the webfinger.js v3 upgrade in #1370 (commit 490b5f7) and ships in
2.0.0-beta.9. webfinger.js v3 added anallow_private_addressesconfig option that defaults tofalse, andWebFinger#resolveAndValidateHostnow throws on any host matching its private/localhost regex before attempting the WebFinger lookup.That breaks:
localhost.192.168.x.x,10.x.x.x, etc.).Fix
The SSRF protection makes sense for server-side webfinger callers (the original concern in silverbucket/webfinger.js#65), but remoteStorage.js runs in browsers, where cross-origin requests are already gated by the same-origin policy / CORS — the flag's threat model doesn't apply there and only blocks legitimate localhost / LAN development.
This PR takes option 2 from the issue: a new
discoveryconfig object, defaulting totrueso beta.9's behaviour is restored, with non-browser embedders able to opt back into the SSRF guard.Breaking changes
discoveryTimeout(a flat top-level constructor option added in beta.9) hasbeen replaced by
discovery.timeoutinside the newdiscoveryconfig object.Update any existing usage:
Closes #1384.