Custom 403 page not available to user who doesn't have 'access content' permissions
simon.males - December 8, 2007 - 04:00
| Project: | Drupal |
| Version: | 7.x-dev |
| Component: | menu system |
| Category: | bug report |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | patch (code needs work) |
Description
If an anonymous user does not permission to access content, then an anonymous user is unable to access a custom 403 (access denied) page.
Steps to reproduce:
- node/add/page > Title 'Custom 403 page' > Save (node/1)
- admin/settings/error-reporting > Default 403 (access denied) page: node/1
- admin/user/permissions > anonymous user: de-select 'access content' under 'node module' > Save
Outcome:
Accessing the site as an anonymous user will display the default Access denied message. The expected result is view the contents of node/1.
I tried to do some digging and discovered that the default 403 page was being casued by MENU_ACCESS_DENIED being returned in menu_execute_active_handler(). I got lost after menu_get_item().

#1
Bug can be replicated in 6.0-rc1, updated version accordingly.
#2
I was able to reproduce this in 6.x-dev. Patch is attached. Removed check for MENU_ACCESS_DENIED, which doesn't make sense when attempting to serve the custom access denied page.
#3
Bug replicated in RC2... I am unsure about current status of patch, as MENU_ACCESS_DENIED may or may not need to stay there.
#4
Anyone mind taking a look at this? It's a relatively minor change and I think should be patched in 6.x, and applied to 7.x as well.
#5
This is still a bug in the production release. It seems the above patch was included in -- but seems to still not give access to the "custom page"
#6
The patch was never applied to core. It still needs review.
#7
Moving to 7.x in hopes of being backported.
Patch still applies successively to HEAD.
#8
Subscribing, and will probably be willing to backport to 6/5.x if needed and if noone beats me to it.
#9
Pretty sure this a non issue in 5.x, I have this setup working in 5.x and was trying to do the same in 6 when I discovered the bug.
#10
Here is a test for Simpletest module for this issue.
The patch #2 has passed the test.
<?php
class TestCase198975 extends DrupalTestCase {
function get_info() {
return array(
'name' => t('[198975] Custom 403 page not available to user who doesn\'t have \'access content\' permissions'),
'desc' => t('If an anonymous user does not permission to access content, then an anonymous user is unable to access a custom 403 (access denied) page.'),
'group' => t('Drupal 7 Tests'),
);
}
function testIssue() {
// save original perms for 'anonymous user'
$anonymous_user_perm_orig = db_result(db_query('SELECT perm FROM {permission} WHERE rid = %d', DRUPAL_ANONYMOUS_RID));
// create a custom 'Default 403 (access denied) page'
$web_user = $this->drupalCreateUserRolePerm(array('edit own page content', 'create page content'));
$this->drupalLoginUser($web_user);
$edit = array();
$edit['title'] = 'Custom 403 page ' . $this->randomName();
$edit['body'] = 'Custom 403 page ' . $this->randomName();
$this->drupalPost('node/add/page', $edit, 'Save');
$node = node_load(array('title' => $edit['title']));
$this->drupalGet('logout');
// set a custom 'Default 403 (access denied) page'
$this->drupalVariableSet('site_403', "node/{$node->nid}");
// check 'anonymous user' can reach custom 403 page with 'access content' perm
db_query("DELETE FROM {permission} WHERE rid = %d", DRUPAL_ANONYMOUS_RID);
db_query("INSERT INTO {permission} (rid, perm) VALUES (%d, '%s')", DRUPAL_ANONYMOUS_RID, 'access content');
$this->drupalGet('admin'); // a common restricted url
$this->assertWantedRaw($edit['title'], "Check with 'access content': %s");
// check 'anonymous user' can reach custom 403 page without 'access content' perm
db_query("DELETE FROM {permission} WHERE rid = %d", DRUPAL_ANONYMOUS_RID);
$this->drupalGet('admin'); // a common restricted url
$this->assertWantedRaw($edit['title'], "Check without 'access content': %s");
// delete the custom 403 page
node_delete($node->nid);
// restore original anonymous user perms
if (!empty($anonymous_user_perm_orig)) {
db_query("INSERT INTO {permission} (rid, perm) VALUES (%d, '%s')", DRUPAL_ANONYMOUS_RID, $anonymous_user_perm_orig);
}
}
}
?>
#11
@Vladimir, thanks for the tests, looks good and should be good for further iterations of the patch as well.
@Everyone: Why would getting a custom 403 page result in a MENU_ACCESS_DENIED return value at all? The idea of this check is if there was no return value, or it was a stock menu constant, the stock error page should be output, if I understand this right.
#12
I'm not sure that I've gone about this the right way, but shouldn't the developer who committed the change be contacted. In this case 'goba'.
http://cvs.drupal.org/viewvc.py/drupal/drupal/includes/common.inc?view=d...
#13
simon.males: Why should I be contacted? The patch you pointed out was http://drupal.org/node/84754 so refer there.
#14
#15
Here's a re-rolled patch that is applicable from Drupal root. Looks good, but not tested.
#16
Bug replicated on a on a clean D7 from head.
Applying http://drupal.org/files/issues/403-access-denied-fix_0.patch doesn't fully work for me:
- the custom access denied page (node/1) is shown, but its body content isn't. Instead, the digit '3' is shown.
- the custom access denied page (node/1) is not shown when trying to access it directly via node/1. In this case you get the default access denied page
#17
Forgot to change status > needs work
#18
jopsesen, i think the behavior you raise in your second point is actually correct... you only want them to be able to view the node in the context of a 403 error.