[3.0] Fixes broken SNI resolution - #9535
Conversation
Signed-off-by: Jon Stovell <jonstovell@gmail.com>
Signed-off-by: Jon Stovell <jonstovell@gmail.com>
|
Seems to work, but please test to confirm, @jdarwood007. |
|
@Sesquipedalian I went looking for why @sbulen was getting The approach here is right, to be clear. Swapping the host for a literal IP was always Why nothing fetches at all. public function isFetchSafe(array $allowed_schemes): bool
{
$is_ascii = $this->is_ascii;
$this->toAscii();
if (
empty($url->scheme) // <- $url is undefined
|| !\in_array($url->scheme, $allowed_schemes)
|| empty($url->host)
|| preg_match('/.../', $url->host)
Then five more, which the first one hides.
Two design points worth your view, which is really why I opened a PR rather than just
Smaller things I also changed
Verification. I ran the URL from the issue through both fetchers, on After: Plus 20 checks over Unrelated, and I deliberately left it: Happy for you to cherry-pick whichever parts you want rather than take #9536 whole — |
725b698 to
0943dbb
Compare
|
How about now, @sbulen? |
|
The new revision picks up nearly all of it, so I've closed #9536 off in my head — this is Writing those tests turned up one thing that is live here right now, and it is a fatal.
|
|
FYI for the AI:
|
|
Both taken, and both checked rather than just accepted.
It went onto the branch on 2026-08-04 (
I've put both into That leaves only #9537 carries that plus the |
Signed-off-by: Jon Stovell <jonstovell@gmail.com>
Signed-off-by: Jon Stovell <jonstovell@gmail.com>
2cdc73e to
be2a729
Compare
|
I just ran a test, & this installed clean, no errors, and in fact the Fetch SMF Files Scheduled Task ran clean, no errors. admin_info_files appears to have been properly refreshed with a clean set of files. To test this, I modified the existing entries & ran Fetch SMF Files. Entries were updated with the proper, current entries. Note to self: You cannot test this by truncating admin_info_files & rerunning. Bad things happen. It needs the old entries laying about... |
Both from the review on #9535, and both cases where the wrong conclusion looks perfectly reasonable from inside the repository. Checking whether a name needs a compatibility shim by looking at the release-2.1 branch finds things that were added to it last month and have never shipped. A mod can only call what was in a release, so the tags are the thing to check, not the branch. And a check that has been taken out is not automatically a regression. FtpConnection::passive() had grown one that reads exactly like SSRF protection, and would be, if FtpConnection fetched from the open web. It does not: it is how the Package Manager reaches an FTP server the admin nominated, which is usually on the LAN, so the check broke the ordinary case. That belongs on FtpFetcher instead. Quotes the review in both places, the way the bug reporting section already quotes #9520. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Signed-off-by: albertlast <mathiaspapealbert@hotmail.com>
Hm. An empty admin_info_files table is something we should be able to recognize and recover from. Could you please open an issue about it, @sbulen, so that we remember to fix it in Alpha 6? |
SimpleMachines#9533 was a regression that shipped, and the decision the fetchers all hang off is reachable with no database and no network, so it seems worth holding onto now that SimpleMachines#9535 has landed. The suite cannot reach the fetchers themselves. What it can reach is Url::isFetchSafe(), and three ways of getting a deterministic answer out of it without a resolver: - Addresses written out in the URL never need a lookup. That covers loopback, private, link local and global, in both families. - Reserved TLDs are refused on the name alone, before the resolver would be asked, so localhost, .local, .internal, .test, .invalid, .example and .onion can be asserted directly. - For anything that does depend on what a name resolves to, withResolvedHosts() seeds the cache that getIPs() keeps, in the same shape as the existing withProxySettings(). That is what lets us say a name resolves to a mix of global and private addresses, or to nothing at all, and get the same answer wherever the suite runs. The cases worth naming: that the URL comes back exactly as it went in, which is the regression itself; that an internationalised host is still UTF-8 afterwards, and that getIPs() and resolvesTo() survive that round trip; that one private address among several global ones refuses the lot; that a name resolving to nothing is not treated as safe; that resolvesTo() matches on the address rather than its spelling; that proxied() reaches its answer without asking the resolver; and that result() has something to return before it reads. Out of reach, and left alone: the three fetchers, CURLOPT_RESOLVE, the post-connection address checks, and ProxyServer::checkRequest(), all of which need a socket. The Subs-Compat shims are out too, since loading that file wants more of Config than the bootstrap sets and defines several hundred functions into the global namespace with no way back. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Signed-off-by: albertlast <mathiaspapealbert@hotmail.com>

Fixes #9533 for 3.0