On a variety of sites I've created I used the Toolbar and Shortcuts modules for non-admin users for better content management. It is possible to use single Shortcut set both for site editors and content creators, i.e. 'Add content', 'Find content', 'Performance' etc. The access to each menu item is properly checked, based on user permissions, i.e. content creators see only the 'Add content' shortcut, while editors both 'Add content' and 'Find content' links. This is not the case of the current HEAD of Drupal-8.

Steps to reproduce:

  1. Create a new user with default permissions (authenticated role for simplicity)
  2. Assign authenticated users permissions to view the toolbar
  3. Assign authenticated users to create content, i.e. Create Article, Edit own Articles, Delete own Articles
  4. Log in as the new user - The Toolbar is visible (OK)
  5. Visit the Shortcuts link on the Toolbar
  6. The 'Add content' link is visible, and points to node/add (redirected to node/add/article, since the user can create only articles) - which is OK, however:
  7. The 'All content' link is visible, as well as other administrative shortcuts (such as Views, Performance) - in Drupal-7 such links are not visible until the user has permissions to access them. If the user clicks 'All content', the Access Denied is thrown, as supposed.

Additional notes (separated bugs?):

  • The 'Manage' link in the toolbar is also visible, although the user does not have any permissions to access administrative sections. With the hook_toolbar_alter I am able to change this behaviour, however I am not sure if this is the desired solution
  • The Shorcut links weight is not respected (it is ok, if you look at the shortcut set edit page, however, on the shortcut bar no changes are made)

Beta phase evaluation

Reference: https://www.drupal.org/core/beta-changes
Issue category Not checking access is a bug ...
Issue priority Major because TODO
Prioritized changes The main goal of this issue is security
Disruption Not disruptive

Comments

mariusz.slonina’s picture

Issue summary: View changes
mariusz.slonina’s picture

StatusFileSize
new928 bytes

In Drupal7 the shortcuts links are rendered through menu_load_links menu_tree, and the access for each item is directly checked. In current HEAD however, entity_load is used, and shortcut_renderable_links function does not take into account the menu link access. From _menu_link_translate I borrowed

$item['access'] = \Drupal::getContainer()->get('access_manager')->checkNamedRoute($item['route_name'], $item['route_parameters'], \Drupal::currentUser());

Simple patch attached - this is my first D8 patch attempt and I don't understand many things going on under the hood, however I am willing to help on this issue

mariusz.slonina’s picture

Status: Active » Needs review

Status: Needs review » Needs work

The last submitted patch, 2: drupal-2216271-0.patch, failed testing.

dawehner’s picture

Priority: Normal » Major

I consider this at least as major. Note: access checking was done previously using menu_tree() so we kinda lost the functionality while converting shortcuts to its own entity type.
You could use this nice little shortcut:

\Drupal::service('access_manager')->checkNamed...
dawehner’s picture

---

lokapujya’s picture

Status: Needs work » Needs review
StatusFileSize
new1 KB

I will try it.

Status: Needs review » Needs work

The last submitted patch, 7: 2216271-7.patch, failed testing.

dawehner’s picture

+++ b/core/modules/shortcut/shortcut.module
@@ -256,10 +256,13 @@ function shortcut_renderable_links($shortcut_set = NULL) {
+    $access = \Drupal::service('access_manager')->checkNamedRoute($shortcut->getRouteName(), $shortcut->getRouteParameters(), \Drupal::currentUser());
+    if ($access) {
+      $links[] = array(
+        'title' => $shortcut->label(),
+        'url' => Url::fromRoute($shortcut->getRouteName(), $shortcut->getRouteParameters()),
+      );
+    }

Note: #2235457: Use link field for shortcut entity probably also fixes the bug. For this case here you could store the $url object and then use $url->access() ...

lokapujya’s picture

I think testAccessShortcutsPermission needs to give the "Administer site configuration" permission to authenticated user in order to fix the 2 remaining fails.

lokapujya’s picture

Status: Needs work » Needs review
StatusFileSize
new809 bytes
new1.79 KB
dawehner’s picture

Issue summary: View changes

That fix for itself is fine.

Added a beta evaluation.

catch’s picture

Priority: Major » Critical
Issue tags: +Security

Information disclosure -> critical.

larowlan queued 11: 2216271-11.patch for re-testing.

Status: Needs review » Needs work

The last submitted patch, 11: 2216271-11.patch, failed testing.

dawehner’s picture

Issue tags: +D8 Accelerate NJ

Working on it in the sky

dawehner’s picture

Status: Needs work » Needs review
StatusFileSize
new2.75 KB

Did not a straight reroll but rather adapted the test coverage to be a little bit more sensible.

Status: Needs review » Needs work

The last submitted patch, 17: 2216271-17.patch, failed testing.

larowlan’s picture

Assigned: Unassigned » larowlan

looking at fails

larowlan’s picture

Status: Needs work » Needs review
StatusFileSize
new3.82 KB
new6.15 KB

So the fix broke existing tests for using shortcuts, which is good - and what we want - so I fixed them and expanded them to ensure we have coverage for 'using' shortcuts.

The new tests in earlier patches for admin lists, didn't handle access there.
So changed that to not show the operation links if no access to the link (we don't let you add them, so why would we let you edit them) - and same story for titles - if you can't access the link - we make the title 'N/A' - the form still works - but you can't get the information disclosure.

This is inline with how we handle those with 'administer comments' who can don't have access to commented entity.

larowlan’s picture

Assigned: larowlan » Unassigned
dawehner’s picture

+++ b/core/modules/shortcut/src/Form/SetCustomize.php
@@ -51,11 +51,12 @@ public function form(array $form, FormStateInterface $form_state) {
+      $url = $shortcut->getUrl();
       $form['shortcuts']['links'][$id]['#attributes']['class'][] = 'draggable';
       $form['shortcuts']['links'][$id]['name'] = array(
         '#type' => 'link',
-        '#title' => $shortcut->getTitle(),
-      ) + $shortcut->getUrl()->toRenderArray();
+        '#title' => $url->access() ? $shortcut->getTitle() : t('N/A'),
+      ) + $url->toRenderArray();
       unset($form['shortcuts']['links'][$id]['name']['#access_callback']);

Not convinced here ... the URL the shortcut links to could also have information in there, as the path aliases might got resolved.

larowlan’s picture

Ok, I can make #access => false on the row, but we then need to fix #theme table (or w/e it uses) to not output an empty row

dawehner’s picture

well that, or just wrap it with an if() statement. I think this is fine for security purposes, honestly.

berdir’s picture

Isn't completely hiding a shortcut row going to mess up the weights which are set there?

lokapujya’s picture

Removing access to see shortcuts by a user with "administer shortcuts" doesn't need to be part of this issue.

larowlan’s picture

Assigned: Unassigned » catch

Removing access to see shortcuts by a user with "administer shortcuts" doesn't need to be part of this issue.

I'm not so sure, we don't let people create shortcuts to paths they have no access to, so we shouldn't let them view/edit them either.
Let's get some committer feedback

catch’s picture

Assigned: catch » Unassigned

'administer shortcuts' doesn't have restrict access: true so unless we add that, then you shouldn't be able to see anything with that permission that you wouldn't otherwise have access to.

catch’s picture

Issue tags: +D8 upgrade path

Tagging.

dawehner’s picture

StatusFileSize
new6.14 KB
new989 bytes

So let's hide it entirely.

@Berdir
As far as I see, we don't recalculate the weights?

Status: Needs review » Needs work

The last submitted patch, 30: 2216271-30.patch, failed testing.

berdir’s picture

I think the JS does, if you move something around?

So access overview with a shortcut that you can't access, move something around, then the hidden one will not be updated and be in a wrong location.

dawehner’s picture

Status: Needs work » Needs review
StatusFileSize
new5.8 KB

@berdir
In this case we have the same problem for menu trees as well, or pretty much everything which uses the JS and access checking.

Just a reroll in the meantime.

berdir’s picture

Sure, I guess it is a very theoretical problem, because which site is going to give that permission to users that do not have full access anyway. But better safe than sorry :)

Status: Needs review » Needs work

The last submitted patch, 33: 2216271-33.patch, failed testing.

dawehner’s picture

Status: Needs work » Needs review
StatusFileSize
new6.48 KB
new964 bytes

Let's fix the missing permissions.

larowlan’s picture

So access overview with a shortcut that you can't access, move something around, then the hidden one will not be updated and be in a wrong location.

But it won't effect you because you'll never see those shortcuts anyway.

It will effect the admin, who can go in an fix it.

In other words I think we can live with that.

larowlan’s picture

Issue summary: View changes
Status: Needs review » Reviewed & tested by the community
StatusFileSize
new75.07 KB
new26.47 KB
new49.95 KB
new32.18 KB
new26.33 KB
new535 bytes
new6.2 KB
+++ b/core/modules/shortcut/src/Form/SetCustomize.php
@@ -77,6 +81,7 @@ public function form(array $form, FormStateInterface $form_state) {
+        '#access' => $url->access(),

This can go now (done in attached)

Manual testing

Super-admin adds shortcut to admin/config/development/performance

Non super admin user has shortcut admin role

shortcut admin role has permission to edit shortcuts

Non super admin user can edit shortcut links but doesn't see links they should not


Non super admin can't see shortcuts with no access

RTBC in my book

larowlan’s picture

Issue summary: View changes
StatusFileSize
new33.74 KB

Missed last screenshot

larowlan’s picture

Issue tags: +CriticalOfficeHours
lokapujya’s picture

+++ b/core/modules/shortcut/src/Tests/ShortcutLinksTest.php
@@ -251,9 +262,17 @@ public function testAccessShortcutsPermission() {
+    $this->assertNoLink('Shortcuts', 0, 'Shortcut link not found on page.');
+    $this->assertNoLink('Cron', 0, 'Cron shortcut link not found on page.');

Remove 2nd parameter.

+++ b/core/modules/shortcut/src/Tests/ShortcutLinksTest.php
@@ -251,9 +262,17 @@ public function testAccessShortcutsPermission() {
     $this->assertNoLink('Shortcuts', 0, 'Shortcut link not found on page.');

same.

note: I see 2 other places in Core with the same problem.

lokapujya’s picture

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

What?

berdir’s picture

Nice find.

AssertNoLink() has no index (the 0). so we're using 0 as the message, and the message as the group.

larowlan’s picture

ooh, lokapujya++

dawehner’s picture

Status: Needs work » Needs review
StatusFileSize
new6.65 KB
new1.26 KB

Good catch!!

jibran’s picture

Status: Needs review » Reviewed & tested by the community

Back to RTBC then.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/modules/shortcut/src/Tests/ShortcutLinksTest.php
@@ -249,11 +260,19 @@ public function testAccessShortcutsPermission() {
+    // Verify that users without the 'administer site configuration' permission
+    // can't see the cron shortcuts.
+    $this->drupalLogin($this->drupalCreateUser(array('access toolbar', 'access shortcuts')));
+    $this->assertNoLink('Shortcuts', 'Shortcut link not found on page.');
+    $this->assertNoLink('Cron', 'Cron shortcut link not found on page.');

Shouldn't we be clicking shortcuts here and then testing that cron does not appear? Because I think what we are verfiying here is something else.

dawehner’s picture

Shouldn't we be clicking shortcuts here and then testing that cron does not appear? Because I think what we are verfiying here is something else.

Well, ... those shortcuts does not appear on the page, as the user doesn't has access to it. How would you click on them?

berdir’s picture

Status: Needs work » Reviewed & tested by the community

Yes. This is all about visibility of the shortcut links. Whether the user can actually visit that page or not has nothing to do with shortcut.

webchick’s picture

Status: Reviewed & tested by the community » Fixed

Great. Committed and pushed to 8.0.x. Thanks!

  • webchick committed 98d2340 on 8.0.x
    Issue #2216271 by larowlan, dawehner, lokapujya, mariusz.slonina, Berdir...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.