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:

  1. The path exists in the menu system.
  2. 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:

  1. Does the domain in the URL match the domain of the site?
  2. If so, is the path in the Drupal menu system?
  3. Convert the absolute URL to a relative one.
  4. 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!

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

TimAlsop’s picture

If 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).

ñull’s picture

Version: 7.x-dev » 8.x-dev
Category: bug » feature

I 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.

ñull’s picture

Deleted second submission because of missing server response.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

jhedstrom’s picture

Not sure how this falls into DX, so removing that tag for now.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

colan’s picture

Issue summary: View changes

I'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.

If so, apply all access checks and controls similar to if the URL was entered as an internal path.

I crossed this out because it should no longer be necessary with the change. Or am I missing something?

colan’s picture

Title: Absolute paths in menu items bypass menu access checks » Convert local absolute menu links to relative to enable access checking & site portability
Issue summary: View changes

Better title (as it's now worded as a feature request), and also added the site portability issue to the IS.

colan’s picture

Version: 8.6.x-dev » 8.8.x-dev
colan’s picture

Status: Needs review » Needs work
colan’s picture

Assigned: Unassigned » colan

Problem is:

Exception: Error: Call to a member function getCurrentRequest() on null
Drupal\menu_link_content\Form\MenuLinkContentForm->reformatInternalLinkIfEnteredAsExternal()() (Line: 139)

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.

colan’s picture

Looks like FormBase::getRequest is the better option as it sets the request stack if it hasn't been set yet.

llamech’s picture

Status: Needs review » Reviewed & tested by the community

I've tested this patch and it works as documented.

colan’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
1.79 KB
1.36 KB

This latest update is:

  • much simpler,
  • keeps extra URL info after the path (e.g. fragments & parameters), and
  • works with subsites (e.g. https://example.com/site1/path).
llamech’s picture

Status: Needs review » Needs work

This works as desired, except for the case where I put in the domain of the site itself, in which case:

  • The "link" field in the form gets saved as an empty string.
  • The link now works, but
  • The edit form for this link can no longer be saved (validation fails because the "link" field is blank).

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.

colan’s picture

Thanks for finding that one. This latest patch seems to handle it, and still works for subdirectory sites.

llamech’s picture

Status: Needs review » Reviewed & tested by the community

Thanks, I've tested and this fixes what I saw in #22. Everything else we've tested looks fine to me.

Status: Reviewed & tested by the community » Needs work
yogeshmpawar’s picture

Assigned: colan » Unassigned
Status: Needs work » Reviewed & tested by the community

All looks good so setting back to RTBC! Tests failure is not related (see #3055648: Frequent random fail in \Drupal\Tests\media_library\FunctionalJavascript\MediaLibraryTest).

Status: Reviewed & tested by the community » Needs work
colan’s picture

Status: Needs work » Reviewed & tested by the community

Happened again.

Status: Reviewed & tested by the community » Needs work
colan’s picture

Status: Needs work » Postponed

I suppose we need to wait for that one then?

colan’s picture

Status: Postponed » Reviewed & tested by the community

Trying again as one possible cause of the problem was fixed.

Status: Reviewed & tested by the community » Needs work
colan’s picture

Status: Needs work » Reviewed & tested by the community

Looks like more unrelated test failures. Trying again.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs tests

Thanks 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:

  1. https://www.drupal.org/docs/8/testing
  2. https://api.drupal.org/api/drupal/core%21core.api.php/group/testing/8.7.x
colan’s picture

Assigned: Unassigned » colan

Indeed! Before getting to those, I just wanted some feedback letting me know that I was on the right track. Thanks for confirming that.

colan’s picture

Assigned: colan » Unassigned

I may not get to this for a while as some other priorities have come up. Feel free to work on the tests, folks.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

jennypanighetti’s picture

I'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.

colan’s picture

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.