Skip to content

[6.x] Fix /index.php request poisoning Site::absoluteUrl#14647

Merged
jasonvarga merged 1 commit into
6.xfrom
bold-emu
May 11, 2026
Merged

[6.x] Fix /index.php request poisoning Site::absoluteUrl#14647
jasonvarga merged 1 commit into
6.xfrom
bold-emu

Conversation

@jasonvarga
Copy link
Copy Markdown
Member

Summary

Fixes #14644.

On a Statamic 6 site without resources/sites.yaml, a direct request to /index.php was returning the homepage with a 200 instead of a 404, and every link in the rendered response was prefixed with /index.php/.... With full static caching, that response got written to disk and served on every subsequent /index.php hit indefinitely — and crawlers then spidered the /index.php/{slug} link graph, poisoning more cached entries.

Root cause

PR #11840 changed Site::absoluteUrl() from request()->getSchemeAndHttpHost() . $url to URL::makeAbsolute($url). The old form was invariant to request entry point; the new form delegates to URL::getRequestRootUrl(), which calls Laravel's url()->to('/') — and that includes the base URL (e.g. /index.php) when the request hits the front controller directly. So on a /index.php request, the site's "absolute URL" inflated to https://host/index.php. Data::findByRequestUrl() then stripped that off the request URL, leaving '' → normalized to / → matched the homepage entry → 200.

Fix

Strip the front-controller script name from URL::getRequestRootUrl() so the result stays invariant to whether the request hit /index.php or /. Same pattern is already used in URL::prependSiteUrl() (line 152–156), so this is consistent with existing convention. Uses pathinfo(request()->getScriptName())['basename'] rather than hardcoding index.php, in case the front controller has been renamed.

This addresses the root cause for all sites with a relative URL — both the missing-sites.yaml fallback case and users who explicitly configure url: / in sites.yaml.

Verification

Restores Statamic 5 behavior. Confirmed end-to-end via php -S:

URL Before fix After fix
/ 200 200
/index.php 200 (homepage) 404
/about/staff 200 200
/index.php/about/staff 200 (poisoned) 404

Test plan

  • New unit test making_urls_absolute_ignores_front_controller_in_request_root covers the regression.
  • Verified the test fails without the patch (returns …com/index.php) and passes with it.
  • Full tests/Facades/UrlTest.php (450 tests), tests/Sites, tests/StaticCaching, tests/Data, tests/Routing all pass.
  • End-to-end verified against php -S with a real Statamic site.
  • Pint passes.

Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com

When a request hits the front controller directly (e.g. /index.php),
Laravel's url()->to('/') returns the URL with the script name appended.
That made URL::makeAbsolute() (and therefore Site::absoluteUrl()) vary
by request entry point, causing fallback-config sites to resolve their
"absolute URL" to https://host/index.php, match the homepage entry,
and serve a 200 (which then gets baked into the static cache).

Strip the script name from getRequestRootUrl() so the result is
invariant. Restores Statamic 5 behavior.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jasonvarga jasonvarga merged commit f81f79e into 6.x May 11, 2026
18 checks passed
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.

/index.php serves homepage (not 404) on sites without resources/sites.yaml, poisoning the static cache

1 participant