I don't know if this is a bug or by design, but on the "access denied" page that is displayed does not show any menus. Is there a reason for this? Any way to work around it?

Comments

adamo’s picture

I have an idea. Currently it looks like during init this module checks for possible hijack attempts, and if it finds one it outputs the basic error page, destroys the session, and then exits.

Instead of doing it that way, how about we log out the user, set current user to anonymous, and then redirect (drupal_goto) to a page explaining why they have been logged out, and then present them with the login form on that page so they can just enter their username and password to continue.

By setting the user to anonymous and then redirecting with drupal_goto, the user will arrive at a completely functional page (with menu's intact, etc), rather than one that appears to be broken. Thoughts?

adamo’s picture

I've done the above on my site and it works well. Instead of being presented with a broken page (no menus, javascript missing, etc) with a link to the log in page, users are presented with a complete page including a login form. Then enter their username and password and it logs them in and brings them to the page they were trying to access.

Here is the modified securepages_prevent_hijack_init() function:

function securepages_prevent_hijack_init() {
  $path = isset($_GET['q']) ? $_GET['q'] : '';
  $page_match = securepages_match($path);

  global $user;
  if ($user->uid > 0 && $page_match && securepages_is_secure() && variable_get('securepages_enable', FALSE)) {
    if (! isset($_COOKIE[SECUREPAGES_SESSID]) ||
    ! drupal_valid_token($_COOKIE[SECUREPAGES_SESSID], 'securepages_prevent_hijack')) {
      watchdog('security',
        t('Session hijack attempt detected for user %user!',
        array('%user' => $user->name)));

      user_module_invoke('logout', $null, $user);
      session_destroy();
      $user = drupal_anonymous_user();
      drupal_goto('securepages/denied', array('destination' => $path));
    }
  }
}

And for the actual error page:

/**
 * Implementation of hook_menu().
 */
function securepages_prevent_hijack_menu() {
  // Access denied page for SecurePages Hijack Prevention module.
  $items['securepages/denied'] = array(
    'title' => t('Session expired'),
    'page callback' => 'securepages_prevent_hijack_denied',
    'access callback' => TRUE,
    'type' => MENU_CALLBACK,
  );

  return $items;
}

/**
 * Page callback for SecurePages Access Denied page
 */
function securepages_prevent_hijack_denied() {
  drupal_set_header('HTTP/1.1 403 Forbidden');
  $login_form = drupal_get_form('user_login');
  
  $output = '<p class="error">Your session has expired.  Please login to continue.</p>';
  $output .= $login_form;
  return $output;
}

Another advantage of doing it this way is that site developers can use hook_menu_alter() to replace the default page with whatever they want.

grendzy’s picture

Category: support » bug
Status: Active » Fixed

This is fixed in http://drupal.org/cvs?commit=363710 though with a different approach, it now uses the standard drupal_access_denied(). This should bring back the blocks, and also means you can set custom error pages at /admin/settings/error-reporting, or use modules like customerror to display whatever you want.

adamo’s picture

Awesome! :)

Status: Fixed » Closed (fixed)

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