Index: securepages.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/securepages/securepages.module,v retrieving revision 1.12.2.7 diff -u -p -r1.12.2.7 securepages.module --- securepages.module 1 Jan 2008 01:18:36 -0000 1.12.2.7 +++ securepages.module 18 Jul 2008 00:44:15 -0000 @@ -1,6 +1,13 @@ user* is secure.'); + } + + // If this is and is supposed to be a secure page, and a user has + // logged in, verify that the secure cookie (set in securepages_user + // hook below) matching the secure token in $_SESSION is present. + global $user; + if ($user->uid > 0 && $page_match && $_SERVER['HTTPS'] && + variable_get('securepages_prevent_hijack', FALSE)) { + if (is_null($_COOKIE[SECUREPAGES_SESSID]) || + $_COOKIE[SECUREPAGES_SESSID] !== $_SESSION[SECUREPAGES_SESSID]) { + watchdog('security', + t('Session hijack attempt detected for user %user!', + array('%user' => theme('placeholder', $user->name)))); + + menu_set_active_item(''); + drupal_set_title(t('Access denied by Secure Pages module')); + $return = t('

The Secure Pages module has detected an invalid '. + 'session access attempt. Please '. + l('log in again', 'logout', array(), + 'destination=user/login') . + '.'); + print theme('page', $return); + module_invoke_all('exit', $url); + exit; + } + } + } /** @@ -78,6 +122,12 @@ function securepages_settings() { '#return_value' => TRUE, '#default_value' => variable_get('securepages_switch', FALSE), ); + $form['securepages_prevent_hijack'] = array( + '#type' => 'checkbox', + '#title' => t('Prevent hijacked sessions from accessing SSL pages'), + '#return_value' => TRUE, + '#default_value' => variable_get('securepages_prevent_hijack', FALSE), + ); $form['securepages_secure'] = array( '#type' => 'radios', '#title' => t('Pages which will be be secure'), @@ -154,6 +204,32 @@ function securepages_link_alter(&$node, } /** + * Implementation of hook_user() + */ +function securepages_user($op, &$edit, &$user, $category = NULL) { + switch ($op) { + case 'login': + if (variable_get('securepages_prevent_hijack', FALSE)) { + if (! $_SERVER['HTTPS']) { + // Admin asked us to prevent hijacks but we have a non-secure login. + watchdog('security', t('Secure Pages detected non-SSL login '. + 'with hijack-prevention enabled.')); + } + + // The user has just logged in. Set a secure cookie (that will + // only be returned to SSL-protected pages) containing a + // non-guessable token, and store that token in the $_SESSION. + $tok = md5(mt_rand() . $edit['pass'] . mt_rand()); + $_SESSION[SECUREPAGES_SESSID] = "$tok"; + $cookie_params = session_get_cookie_params(); + setcookie(SECUREPAGES_SESSID, $tok, time() + $cookie_params[lifetime], + $cookie_params[path], $cookie_params[domain], 1); + } + break; + } +} + +/** * securepage_goto() * * Redirects the current page to the secure or insecure version.