Fix previousPath() returning full URL for external referrers (fixes laravel/framework#57456)#5
Open
JoshSalway wants to merge 2 commits into12.xfrom
Open
Fix previousPath() returning full URL for external referrers (fixes laravel/framework#57456)#5JoshSalway wants to merge 2 commits into12.xfrom
JoshSalway wants to merge 2 commits into12.xfrom
Conversation
Adds tests to verify previousPath() correctly extracts path component when the referer header contains an external domain URL or when the application is deployed in a subdirectory. Refs laravel#57456 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
previousPath() used str_replace to strip the app URL from the referer, which returned the full external URL when the referer came from a different domain. Switch to parse_url() to extract the path component directly, and strip the base path for subdirectory deployments. Backport of laravel#59159 (13.x) to 12.x. Fixes laravel#57456 Co-Authored-By: Claude Opus 4.6 (1M context) <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.
Summary
Fixes laravel#57456 --
previousPath()returns the full URL path from external referrers instead of just the path portion relative to the application. When a user arrives fromhttps://google.com/search?q=laravel,previousPath()returns/searchinstead of/(no meaningful previous path within the app).Root Cause
The bug exists because
previousPath()uses string subtraction (str_replace($this->to('/'), '', ...)) to strip the application's base URL from the referrer URL. When the referrer is an external domain (e.g.,https://google.com/search),str_replacefinds no match and returns the full external path/searchunchanged. The method assumes the referrer always comes from the same domain, which is incorrect for external referrers, bookmarks, and cross-origin links.Additionally, the
str_replaceapproach fails when the application is mounted at a sub-path (e.g.,https://example.com/subdir/) because it performs a literal string replacement that can't properly handle base path stripping.Why This Fix Works
This fix works because it uses
parse_url($url, PHP_URL_PATH)to extract only the path component from the referrer URL, completely ignoring the domain and query string. For base path stripping, it usesparse_url($this->to('/'), PHP_URL_PATH)to get the application's base path and removes it with a regex anchor. This approach is domain-agnostic -- it correctly extracts the path regardless of whether the referrer is internal or external. External referrer paths are returned as-is, which is the correct behavior (the path is meaningful to the caller).Alternatives Considered
We chose this approach over comparing domains and returning
/for external referrers because: (1) the method's contract is to return a path, not to validate origin; (2) some applications legitimately usepreviousPath()to inspect where users came from, even external paths; (3) theparse_urlapproach is simpler, handles edge cases (missing paths, query strings, fragments) natively, and correctly handles sub-path deployments that the oldstr_replaceapproach broke.Files Changed
src/Illuminate/Routing/UrlGenerator.php-- RewrotepreviousPath()to useparse_url()instead ofstr_replace()tests/Routing/RoutingUrlGeneratorTest.php-- Added tests for external referrers and sub-path deployments