Index: securepages.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/securepages/securepages.module,v retrieving revision 1.15.2.4 diff -u -p -r1.15.2.4 securepages.module --- securepages.module 9 Mar 2008 22:47:53 -0000 1.15.2.4 +++ securepages.module 23 Jul 2008 23:28:57 -0000 @@ -1,6 +1,8 @@ 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' => $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 log in again.
', + array('!url' => url('logout', array('query'=>array('destination' => 'user/login'))))); + print theme('page', $return); + module_invoke_all('exit', $url); + exit; + } + } +} + +/** * Implementation of hook_menu() */ function securepages_menu() { @@ -75,6 +118,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'), @@ -143,6 +192,33 @@ 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() *