Repository navigation
Conversation
Appwrite validates a migration source's endpoint before it connects, but the source then resolves the host again for every request and follows redirects anywhere, so a rebinding host or a redirect reaches the internal network. utopia-php/client already checks each connection and redirect hop against the address it actually reached through Destinations; this lets a caller hand a target that policy instead of re-implementing pinning. Target::setDestinations() applies to the target's own requests, and the Appwrite source passes it on to its SDK client through a thin subclass that adds it to the HTTP client the SDK builds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
abnegate
added a commit
to appwrite/appwrite
that referenced
this pull request
Oct 15, 2026
Main moved to utopia-php/migration 3.x, whose source requests go through utopia-php/client, so the 2.0.x resolver branch no longer applies. Require utopia-php/migration#240 instead, which passes a Destinations policy through. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Member
Author
|
Superseded by #229, which merged the resolver and redirect controls on |
This was referenced Oct 15, 2026
Member
Author
|
Ported to appwrite/appwrite#14508. Migration now lives in |
imtia33
pushed a commit
to imtia33/appwrite
that referenced
this pull request
Oct 15, 2026
Ports utopia-php/migration#240. Target::setDestinations() hands a Utopia\Client\Destinations to the client Target::call() builds, and the Appwrite source applies it to its SDK client as well. utopia-php/client checks every connection and redirect hop against the address curl actually reached, and refuses proxies under a restricting policy, so a host that rebinds or redirects cannot reach an address the caller did not admit. Unset, requests connect anywhere, as before. The resolver controls from appwrite#229 stay: appwrite#14034 uses setResolver() today, and the two compose. The changelog gains a 4.0.0 section for this and for what landed since 3.1.2 without an entry, including the redirect default that makes it a major. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
What
Target::setDestinations(Destinations)confines a target's requests to aUtopia\Client\Destinationspolicy. The Appwrite source also applies it to its SDK client, throughSources\Appwrite\Client, a subclass of the SDK 30 client that adds the policy to the HTTP client the SDK builds (createHttpClient()).Unset, nothing changes: requests connect anywhere, as before.
Why
appwrite/appwrite#14034 checks an Appwrite migration source's endpoint before it connects. The source then resolves the host again on every request and follows redirects, so a host that rebinds, or redirects, still reaches the internal network.
utopia-php/client already solves this. Its curl adapter checks every connection and redirect hop against the address curl actually connected to, and refuses proxies when the policy restricts addresses. On 3.x every source request goes through utopia-php/client, either
Target::call()or the SDK 30 client. So the library only has to pass the caller's policy through.This replaces the resolver hook in #229 and #230. Those predate the move to utopia-php/client: they pinned
CURLOPT_RESOLVEentries and re-implemented the SDK's curl call.Tests
tests/Migration/Unit/General/TargetDestinationsTest.phpruns a local HTTP server on 127.0.0.1 and covers:PublicInternetrefusing it;PublicInternetwith a127.0.0.0/8range admitting it;6 of the 7 fail without the change. The default case passes either way.
Locally, Pint passes and the full unit suite passes (161 tests). PHPStan level 3 reports no errors in the changed files. The only errors it reports are 10 that
MigrationCLITestalready has onmain.Not verified
🤖 Generated with Claude Code