Problem
As it stands, the menu system checks all menu paths pointing to internal links (ie, node/add or user/logout) upon submission to verify:
- The path exists in the menu system.
- The user has the proper permissions to access that path.
Furthermore, when a menu is being rendered, paths that the current user does not have access to are not rendered in the menu.
The problem begins when the user creates a menu item using an absolute URL pointing to an internal system path. For example, with Clean URLs, the user could create a menu item using the path 'http://www.example.com/admin'.
This avoids all the access checks that are made when the path is entered as an internal path.
The other problem is that the site is no longer portable as links will break when migrated between Dev, Staging and Prod environments (or the domain is changed entirely).
This has happened on several client's sites when they add menu items by surfing to the page they want to add, copying the URL from the address bar, then pasting into the menu form.
Proposed solution
I would suggest that when the menu system parses absolute URLs, it should check:
- Does the domain in the URL match the domain of the site?
- If so, is the path in the Drupal menu system?
- Convert the absolute URL to a relative one.
If so, apply all access checks and controls similar to if the URL was entered as an internal path.This shouldn't be necessary because core now treats the URL as relative.
I am putting this on my list of 'bugs to fix'. However, I can't guarantee I will get around to it soon. If someone wants to take a crack at it, please, take ownership and tackle it. Chances are you are more familiar with the menu system than I am anyways!
Comment | File | Size | Author |
---|---|---|---|
#23 | drupal-reformat_internal_menu_links-483150-23.patch | 1.85 KB | colan |
#23 | interdiff-483150-21-23.diff | 1.02 KB | colan |
#19 | drupal-reformat_internal_menu_links-483150-19.patch | 2.19 KB | colan |
#16 | drupal-reformat_internal_menu_links-483150-16.patch | 2.25 KB | colan |
Comments
Comment #3
TimAlsop CreditAttribution: TimAlsop commentedIf a user logs onto http://www.example.com and there is a menu item which links to http://sub1.example.com - how is the menu system going to know whether the user (anonymous or logged on user) has access to the URL ? Of course, you can check if the URL is in any affiliated domain or in same domain as an alias, but how do you plan to check if user can access ? The only way I can see that you would be able to do this is to allow the menu item to have a configuration where roles can be added, and then the roles can be setup, just like nodes and blocks can have roles to determine access (assuming a roles based access control module is being used).
Comment #4
ñull CreditAttribution: ñull commentedI think I like point 1 and 2 of the proposed solution, which in fact is a feature request. On my D6 site repetitively users put full URLs that in fact should be internal. This causes great trouble in our sandboxes where these links point to production site (sandboxes and production don't have the same domain).
Average users do not know how to handle absolute and relative paths. Paths are part of command line culture and most users belong to GUI culture.
I think that when an absolute path is entered that points to an internal page, then it should be automatically changed to a relative (with Ajax?).
Point 3 is not needed, because Drupal takes care of that already. Internal menu links that point to un authorised content will not appear in a menu. That is another reason to automatically change the path to an internal path, because external paths will appear always, no matter if the user is authorised.
Comment #5
ñull CreditAttribution: ñull commentedDeleted second submission because of missing server response.
Comment #11
jhedstromNot sure how this falls into DX, so removing that tag for now.
Comment #13
colanI'm in agreement with #4. Rather than propagating the problem (of moving the site to a different environment/domain and having links break), the absolute links should be converted to relative. Proposal updated.
I crossed this out because it should no longer be necessary with the change. Or am I missing something?
Comment #14
colanBetter title (as it's now worded as a feature request), and also added the site portability issue to the IS.
Comment #15
colanComment #16
colanComment #18
colanProblem is:
It seems like
$this->requestStack
isn't defined, but it should be coming from FormBase. I'll add a local class variable to work around the problem.Comment #19
colanLooks like FormBase::getRequest is the better option as it sets the request stack if it hasn't been set yet.
Comment #20
llamechI've tested this patch and it works as documented.
Comment #21
colanThis latest update is:
https://example.com/site1/path
).Comment #22
llamechThis works as desired, except for the case where I put in the domain of the site itself, in which case:
If I put a slash in the "link" field, it gets automatically replaced with a
"<front>"
token. Presumably, that's the behaviour we would prefer when the domain of the site is entered.Comment #23
colanThanks for finding that one. This latest patch seems to handle it, and still works for subdirectory sites.
Comment #24
llamechThanks, I've tested and this fixes what I saw in #22. Everything else we've tested looks fine to me.
Comment #26
yogeshmpawarAll looks good so setting back to RTBC! Tests failure is not related (see #3055648: Frequent random fail in \Drupal\Tests\media_library\FunctionalJavascript\MediaLibraryTest).
Comment #28
colanHappened again.
Comment #30
colanI suppose we need to wait for that one then?
Comment #31
colanTrying again as one possible cause of the problem was fixed.
Comment #33
colanLooks like more unrelated test failures. Trying again.
Comment #34
alexpottThanks for filing this feature request. It looks really useful. However in order to commit a feature we need an automated to test to prove that the feature works and ensure that we don't break it in the future. For more information about writing tests in Drupal 8 see the following links:
Comment #35
colanIndeed! Before getting to those, I just wanted some feedback letting me know that I was on the right track. Thanks for confirming that.
Comment #36
colanI may not get to this for a while as some other priorities have come up. Feel free to work on the tests, folks.
Comment #38
jennypanighetti CreditAttribution: jennypanighetti commentedI'm not sure this is the right place for this, and I might open a new issue for this instead, but I just wanted to chime in on using relative URLs.My problem with using /relative URLs in the Menus is that it only looks for *node* aliases, not also View aliases. I had to explicitly use the absolute URL when pointing to a view while testing (before using the Menu settings in the view).This is also the case where a second menu needs to link to the same pages, and if they're Views, a relative URL won't work; it completely breaks the site.Nevermind, it was a different problem.
Comment #39
colan