diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/book/book.install | 6 | ||||
-rw-r--r-- | modules/dblog/dblog.admin.inc | 15 | ||||
-rw-r--r-- | modules/node/node.admin.inc | 13 | ||||
-rw-r--r-- | modules/openid/openid.inc | 8 | ||||
-rw-r--r-- | modules/openid/openid.module | 6 | ||||
-rw-r--r-- | modules/simpletest/tests/session.test | 113 | ||||
-rw-r--r-- | modules/simpletest/tests/session_test.module | 22 | ||||
-rw-r--r-- | modules/system/system.admin.inc | 4 | ||||
-rw-r--r-- | modules/system/system.install | 8 | ||||
-rw-r--r-- | modules/user/user.admin.inc | 10 | ||||
-rw-r--r-- | modules/user/user.module | 4 |
11 files changed, 73 insertions, 136 deletions
diff --git a/modules/book/book.install b/modules/book/book.install index 3dc117282..c0ea1be01 100644 --- a/modules/book/book.install +++ b/modules/book/book.install @@ -134,8 +134,8 @@ function book_update_6000() { db_create_table($ret, 'book', $schema['book']); - drupal_set_session('book_update_6000_orphans', array('from' => 0)); - drupal_set_session('book_update_6000', array()); + $_SESSION['book_update_6000_orphans'] = array('from' => 0); + $_SESSION['book_update_6000'] = array(); $result = db_query("SELECT * from {book_temp} WHERE parent = 0"); // Collect all books - top-level nodes. @@ -152,7 +152,7 @@ function book_update_6000() { return $ret; } } - elseif ($_SESSION['book_update_6000_orphans']) { + elseif (isset($_SESSION['book_update_6000_orphans'])) { // Do the first batched part of the update - collect orphans. $update_count = 400; // Update this many at a time. diff --git a/modules/dblog/dblog.admin.inc b/modules/dblog/dblog.admin.inc index 945a85a0e..53389586d 100644 --- a/modules/dblog/dblog.admin.inc +++ b/modules/dblog/dblog.admin.inc @@ -284,10 +284,6 @@ function _dblog_format_message($dblog) { * @see dblog_filter_form_validate() */ function dblog_filter_form() { - if (!isset($_SESSION['dblog_overview_filter'])) { - drupal_set_session('dblog_overview_filter', array()); - } - $session = &$_SESSION['dblog_overview_filter']; $filters = dblog_filters(); $form['filters'] = array( @@ -305,8 +301,8 @@ function dblog_filter_form() { '#size' => 8, '#options' => $filter['options'], ); - if (!empty($session[$key])) { - $form['filters']['status'][$key]['#default_value'] = $session[$key]; + if (!empty($_SESSION['dblog_overview_filter'][$key])) { + $form['filters']['status'][$key]['#default_value'] = $_SESSION['dblog_overview_filter'][$key]; } } @@ -314,7 +310,7 @@ function dblog_filter_form() { '#type' => 'submit', '#value' => t('Filter'), ); - if (!empty($session)) { + if (!empty($_SESSION['dblog_overview_filter'])) { $form['filters']['buttons']['reset'] = array( '#type' => 'submit', '#value' => t('Reset') @@ -343,15 +339,12 @@ function dblog_filter_form_submit($form, &$form_state) { case t('Filter'): foreach ($filters as $name => $filter) { if (isset($form_state['values'][$name])) { - if (!isset($_SESSION['dblog_overview_filter'])) { - drupal_set_session('dblog_overview_filter', array()); - } $_SESSION['dblog_overview_filter'][$name] = $form_state['values'][$name]; } } break; case t('Reset'): - drupal_set_session('dblog_overview_filter', array()); + $_SESSION['dblog_overview_filter'] = array(); break; } return 'admin/reports/dblog'; diff --git a/modules/node/node.admin.inc b/modules/node/node.admin.inc index 74d41146b..67790b1f4 100644 --- a/modules/node/node.admin.inc +++ b/modules/node/node.admin.inc @@ -171,7 +171,8 @@ function node_build_filter_query() { // Build query $where = $args = array(); $join = ''; - foreach ($_SESSION['node_overview_filter'] as $index => $filter) { + $filter_data = isset($_SESSION['node_overview_filter']) ? $_SESSION['node_overview_filter'] : array(); + foreach ($filter_data as $index => $filter) { list($key, $value) = $filter; switch ($key) { case 'status': @@ -202,10 +203,7 @@ function node_build_filter_query() { * Return form for node administration filters. */ function node_filter_form() { - if (!isset($_SESSION['node_overview_filter'])) { - drupal_set_session('node_overview_filter', array()); - } - $session = &$_SESSION['node_overview_filter']; + $session = isset($_SESSION['node_overview_filter']) ? $_SESSION['node_overview_filter'] : array(); $filters = node_filters(); $i = 0; @@ -320,9 +318,6 @@ function node_filter_form_submit($form, &$form_state) { $flat_options = form_options_flatten($filters[$filter]['options']); if (isset($flat_options[$form_state['values'][$filter]])) { - if (!isset($_SESSION['node_overview_filter'])) { - drupal_set_session('node_overview_filter', array()); - } $_SESSION['node_overview_filter'][] = array($filter, $form_state['values'][$filter]); } } @@ -331,7 +326,7 @@ function node_filter_form_submit($form, &$form_state) { array_pop($_SESSION['node_overview_filter']); break; case t('Reset'): - drupal_set_session('node_overview_filter', array()); + $_SESSION['node_overview_filter'] = array(); break; } } diff --git a/modules/openid/openid.inc b/modules/openid/openid.inc index 9bc4de789..debf16169 100644 --- a/modules/openid/openid.inc +++ b/modules/openid/openid.inc @@ -61,6 +61,10 @@ function openid_redirect_http($url, $message) { $sep = (strpos($url, '?') === FALSE) ? '?' : '&'; header('Location: ' . $url . $sep . implode('&', $query), TRUE, 302); + + // Commit session data before redirecting. + drupal_session_commit(); + exit; } @@ -73,6 +77,10 @@ function openid_redirect($url, $message) { $output .= '<script type="text/javascript">document.getElementById("openid-redirect-form").submit();</script>'; $output .= "</body></html>\n"; print $output; + + // Commit session data before redirecting. + drupal_session_commit(); + exit; } diff --git a/modules/openid/openid.module b/modules/openid/openid.module index 03053333f..a879ccdb7 100644 --- a/modules/openid/openid.module +++ b/modules/openid/openid.module @@ -174,9 +174,6 @@ function openid_begin($claimed_id, $return_to = '', $form_values = array()) { } // Store discovered information in the users' session so we don't have to rediscover. - if (!isset($_SESSION['openid'])) { - drupal_set_session('openid', array()); - } $_SESSION['openid']['service'] = $services[0]; // Store the claimed id $_SESSION['openid']['claimed_id'] = $claimed_id; @@ -434,9 +431,6 @@ function openid_authentication($response) { // We were unable to register a valid new user, redirect to standard // user/register and prefill with the values we received. drupal_set_message(t('OpenID registration failed for the reasons listed. You may register now, or if you already have an account you can <a href="@login">log in</a> now and add your OpenID under "My Account"', array('@login' => url('user/login'))), 'error'); - if (!isset($_SESSION['openid'])) { - drupal_set_session('openid', array()); - } $_SESSION['openid']['values'] = $form_state['values']; // We'll want to redirect back to the same place. $destination = drupal_get_destination(); diff --git a/modules/simpletest/tests/session.test b/modules/simpletest/tests/session.test index d713cbb38..d53c14c20 100644 --- a/modules/simpletest/tests/session.test +++ b/modules/simpletest/tests/session.test @@ -31,12 +31,15 @@ class SessionTestCase extends DrupalWebTestCase { // Test session hardening code from SA-2008-044. $user = $this->drupalCreateUser(array('access content')); + // Enable sessions. $this->sessionReset($user->uid); + // Make sure the session cookie is set as HttpOnly. $this->drupalLogin($user); $this->assertTrue(preg_match('/HttpOnly/i', $this->drupalGetHeader('Set-Cookie', TRUE)), t('Session cookie is set as HttpOnly.')); $this->drupalLogout(); + // Verify that the session is regenerated if a module calls exit // in hook_user_login(). user_save($user, array('name' => 'session_test_user')); @@ -46,6 +49,7 @@ class SessionTestCase extends DrupalWebTestCase { preg_match('/\s*session_id:(.*)\n/', $this->drupalGetContent(), $matches); $this->assertTrue(!empty($matches[1]) , t('Found session ID before logging in.')); $original_session = $matches[1]; + // We cannot use $this->drupalLogin($user); because we exit in // session_test_user_login() which breaks a normal assertion. $edit = array( @@ -69,12 +73,16 @@ class SessionTestCase extends DrupalWebTestCase { * drupal_session_count() since session data is already generated here. */ function testDataPersistence() { + // At the very start, we have no session. + $expected_anonymous = 0; + $expected_authenticated = 0; + $user = $this->drupalCreateUser(array('access content')); // Enable sessions. $this->sessionReset($user->uid); $this->drupalLogin($user); - $this->session_count_authenticated = $this->session_count++; + $expected_authenticated++; $value_1 = $this->randomName(); $this->drupalGet('session-test/set/' . $value_1); @@ -97,51 +105,56 @@ class SessionTestCase extends DrupalWebTestCase { // Logout the user and make sure the stored value no longer persists. $this->drupalLogout(); + $expected_authenticated--; + $this->sessionReset(); $this->drupalGet('session-test/get'); - // Session count should go up since we're accessing anonymously now. - $this->session_count_anonymous = $this->session_count++; $this->assertNoText($value_1, t("After logout, previous user's session data is not available."), t('Session')); + // Now try to store some data as an anonymous user. $value_3 = $this->randomName(); $this->drupalGet('session-test/set/' . $value_3); $this->assertText($value_3, t('Session data stored for anonymous user.'), t('Session')); $this->drupalGet('session-test/get'); $this->assertText($value_3, t('Session correctly returned the stored data for an anonymous user.'), t('Session')); + // Session count should go up since we have started an anonymous session now. + $expected_anonymous++; + // Try to store data when drupal_save_session(FALSE). $value_4 = $this->randomName(); $this->drupalGet('session-test/no-set/' . $value_4); $this->assertText($value_4, t('The session value was correctly passed to session-test/no-set.'), t('Session')); $this->drupalGet('session-test/get'); $this->assertText($value_3, t('Session data is not saved for drupal_save_session(FALSE).'), t('Session')); - // Logout and get first user back in. Sessions shouldn't persist through - // logout, so the data won't be on the page. + // Login, the data should persist. $this->drupalLogin($user); + $expected_anonymous--; + $expected_authenticated++; $this->sessionReset($user->uid); $this->drupalGet('session-test/get'); $this->assertNoText($value_1, t('Session has persisted for an authenticated user after logging out and then back in.'), t('Session')); - // Logout and create another user. + // Change session and create another user. $user2 = $this->drupalCreateUser(array('access content')); $this->sessionReset($user2->uid); $this->drupalLogin($user2); - $this->session_count_authenticated = $this->session_count++; + $expected_authenticated++; // Perform drupal_session_count tests here in order to use the session data already generated. // Test absolute count. $anonymous = drupal_session_count(0, TRUE); $authenticated = drupal_session_count(0, FALSE); - $this->assertEqual($anonymous + $authenticated, $this->session_count, t('Correctly counted @count total sessions.', array('@count' => $this->session_count)), t('Session')); + $this->assertEqual($anonymous + $authenticated, $expected_anonymous + $expected_authenticated, t('@count total sessions (expected @expected).', array('@count' => $anonymous + $authenticated, '@expected' => $expected_anonymous + $expected_authenticated)), t('Session')); // Test anonymous count. - $this->assertEqual($anonymous, $this->session_count_anonymous, t('Correctly counted @count anonymous sessions.', array('@count' => $anonymous)), t('Session')); + $this->assertEqual($anonymous, $expected_anonymous, t('@count anonymous sessions (expected @expected).', array('@count' => $anonymous, '@expected' => $expected_anonymous)), t('Session')); // Test authenticated count. - $this->assertEqual($authenticated, $this->session_count_authenticated, t('Correctly counted @count authenticated sessions.', array('@count' => $authenticated)), t('Session')); + $this->assertEqual($authenticated, $expected_authenticated, t('@count authenticated sessions (expected @expected).', array('@count' => $authenticated, '@expected' => $expected_authenticated)), t('Session')); // Should return 0 sessions from 1 second from now. - $this->assertEqual(drupal_session_count(time() + 1), 0, t('Correctly returned 0 sessions newer than the current time.'), t('Session')); + $this->assertEqual(drupal_session_count(time() + 1), 0, t('0 sessions newer than the current time.'), t('Session')); } @@ -149,83 +162,39 @@ class SessionTestCase extends DrupalWebTestCase { * Test that empty anonymous sessions are destroyed. */ function testEmptyAnonymousSession() { - // With caching disabled, a session is always started. + // Verify that no session is automatically created for anonymous user. $this->drupalGet(''); $this->assertSessionCookie(FALSE); - $this->assertSessionStarted(TRUE); $this->assertSessionEmpty(TRUE); + // The same behavior is expected when caching is enabled. variable_set('cache', CACHE_NORMAL); - - // During this request the session is destroyed in drupal_page_footer(), - // and the session cookie is unset. $this->drupalGet(''); - $this->assertSessionCookie(TRUE); - $this->assertSessionStarted(TRUE); + $this->assertSessionCookie(FALSE); $this->assertSessionEmpty(TRUE); $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS', t('Page was not cached.')); - // When PHP deletes a cookie, it sends "Set-Cookie: cookiename=deleted; - // expires=..." - $this->assertTrue(preg_match('/SESS\w+=deleted/', $this->drupalGetHeader('Set-Cookie')), t('Session cookie was deleted.')); - - // Verify that the session cookie was actually deleted. - $this->drupalGet(''); - $this->assertSessionCookie(FALSE); - $this->assertSessionStarted(FALSE); - $this->assertFalse($this->drupalGetHeader('Set-Cookie'), t('New session was not started.')); // Start a new session by setting a message. $this->drupalGet('session-test/set-message'); - $this->assertSessionCookie(FALSE); - $this->assertSessionStarted(FALSE); + $this->assertSessionCookie(TRUE); $this->assertTrue($this->drupalGetHeader('Set-Cookie'), t('New session was started.')); - // Display the message. + // Display the message, during the same request the session is destroyed + // and the session cookie is unset. $this->drupalGet(''); - $this->assertSessionCookie(TRUE); - $this->assertSessionStarted(TRUE); + $this->assertSessionCookie(FALSE); $this->assertSessionEmpty(FALSE); $this->assertFalse($this->drupalGetHeader('X-Drupal-Cache'), t('Caching was bypassed.')); $this->assertText(t('This is a dummy message.'), t('Message was displayed.')); - - // During this request the session is destroyed in _drupal_bootstrap(), - // and the session cookie is unset. - $this->drupalGet(''); - $this->assertSessionCookie(TRUE); - $this->assertSessionStarted(TRUE); - $this->assertSessionEmpty(TRUE); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', t('Page was cached.')); - $this->assertNoText(t('This is a dummy message.'), t('Message was not cached.')); $this->assertTrue(preg_match('/SESS\w+=deleted/', $this->drupalGetHeader('Set-Cookie')), t('Session cookie was deleted.')); // Verify that session was destroyed. $this->drupalGet(''); $this->assertSessionCookie(FALSE); - $this->assertSessionStarted(FALSE); + $this->assertSessionEmpty(TRUE); + $this->assertNoText(t('This is a dummy message.'), t('Message was not cached.')); $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', t('Page was cached.')); $this->assertFalse($this->drupalGetHeader('Set-Cookie'), t('New session was not started.')); - - // Verify that modifying $_SESSION without having started a session - // generates a watchdog message, and that no messages have been generated - // so far. - $this->assertEqual($this->getWarningCount(), 0, t('No watchdog messages have been generated')); - $this->drupalGet('/session-test/set-not-started'); - $this->assertSessionCookie(FALSE); - $this->assertSessionStarted(FALSE); - $this->assertEqual($this->getWarningCount(), 1, t('1 watchdog messages has been generated')); - } - - /** - * Count watchdog messages about modifying $_SESSION without having started a - * session. - */ - function getWarningCount() { - return db_select('watchdog') - ->condition('type', 'session') - ->condition('message', '$_SESSION is non-empty yet no code has called drupal_session_start().') - ->countQuery() - ->execute() - ->fetchField(); } /** @@ -250,22 +219,10 @@ class SessionTestCase extends DrupalWebTestCase { */ function assertSessionCookie($sent) { if ($sent) { - $this->assertIdentical($this->drupalGetHeader('X-Session-Cookie'), '1', t('Session cookie was sent.')); - } - else { - $this->assertIdentical($this->drupalGetHeader('X-Session-Cookie'), '0', t('Session cookie was not sent.')); - } - } - - /** - * Assert whether session was started during the bootstrap process. - */ - function assertSessionStarted($started) { - if ($started) { - $this->assertIdentical($this->drupalGetHeader('X-Session-Started'), '1', t('Session was started.')); + $this->assertNotNull($this->session_id, t('Session cookie was sent.')); } else { - $this->assertIdentical($this->drupalGetHeader('X-Session-Started'), '0', t('Session was not started.')); + $this->assertNull($this->session_id, t('Session cookie was not sent.')); } } diff --git a/modules/simpletest/tests/session_test.module b/modules/simpletest/tests/session_test.module index 352a21e25..eb656ce80 100644 --- a/modules/simpletest/tests/session_test.module +++ b/modules/simpletest/tests/session_test.module @@ -51,22 +51,10 @@ function session_test_menu() { * Implement hook_boot(). */ function session_test_boot() { - header('X-Session-Cookie: ' . intval(isset($_COOKIE[session_name()]))); - header('X-Session-Started: ' . intval(drupal_session_is_started())); header('X-Session-Empty: ' . intval(empty($_SESSION))); } /** - * Implement hook_init(). - */ -function session_test_init() { - // hook_init() is called later in the bootstrap process, but not in cached - // requests. Here the header set in hook_boot() is overwritten, so the - // session state is reported as late in the bootstrap process as possible. - header('X-Session-Started: ' . intval(drupal_session_is_started())); -} - -/** * Page callback, prints the stored session value to the screen. */ function _session_test_get() { @@ -82,7 +70,7 @@ function _session_test_get() { * Page callback, stores a value in $_SESSION['session_test_value']. */ function _session_test_set($value) { - drupal_set_session('session_test_value', $value); + $_SESSION['session_test_value'] = $value; return t('The current value of the stored session variable has been set to %val', array('%val' => $value)); } @@ -100,6 +88,12 @@ function _session_test_no_set($value) { * Menu callback: print the current session ID. */ function _session_test_id() { + // Set a value in $_SESSION, so that drupal_session_commit() will start + // a session. + $_SESSION['test'] = 'test'; + + drupal_session_commit(); + return 'session_id:' . session_id() . "\n"; } @@ -119,7 +113,7 @@ function _session_test_set_message() { * having started the session in advance. */ function _session_test_set_not_started() { - if (!drupal_session_is_started()) { + if (!drupal_session_will_start()) { $_SESSION['session_test_value'] = t('Session was not started'); } } diff --git a/modules/system/system.admin.inc b/modules/system/system.admin.inc index 83cca4ad2..6fd477674 100644 --- a/modules/system/system.admin.inc +++ b/modules/system/system.admin.inc @@ -1734,7 +1734,7 @@ function system_clean_url_settings() { // When accessing this form using a non-clean URL, allow a re-check to make // sure clean URLs can be disabled at all times. $available = FALSE; - if (strpos(request_uri(), '?q=') === FALSE || drupal_get_session('clean_url')) { + if (strpos(request_uri(), '?q=') === FALSE || !empty($_SESSION['clean_url'])) { $available = TRUE; } else { @@ -1745,7 +1745,7 @@ function system_clean_url_settings() { } if ($available) { - drupal_set_session('clean_url', TRUE); + $_SESSION['clean_url'] = TRUE; $form['clean_url'] = array( '#type' => 'checkbox', diff --git a/modules/system/system.install b/modules/system/system.install index 2bfe95db7..1f535c586 100644 --- a/modules/system/system.install +++ b/modules/system/system.install @@ -1983,10 +1983,10 @@ function system_update_6021() { // Multi-part update if (!isset($_SESSION['system_update_6021'])) { db_add_field($ret, 'menu', 'converted', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, 'size' => 'tiny')); - drupal_set_session('system_update_6021_max', db_result(db_query('SELECT COUNT(*) FROM {menu}'))); - drupal_set_session('menu_menu_map', array(1 => 'navigation')); + $_SESSION['system_update_6021_max'] = db_result(db_query('SELECT COUNT(*) FROM {menu}')); + $_SESSION['menu_menu_map'] = array(1 => 'navigation'); // 0 => FALSE is for new menus, 1 => FALSE is for the navigation. - drupal_set_session('menu_item_map', array(0 => FALSE, 1 => FALSE)); + $_SESSION['menu_item_map'] = array(0 => FALSE, 1 => FALSE); $table = array( 'fields' => array( 'menu_name' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''), @@ -1997,7 +1997,7 @@ function system_update_6021() { ); db_create_table($ret, 'menu_custom', $table); db_query("INSERT INTO {menu_custom} (menu_name, title, description) VALUES ('%s', '%s', '%s')", $menus['navigation']); - drupal_set_session('system_update_6021', 0); + $_SESSION['system_update_6021'] = 0; } $limit = 50; diff --git a/modules/user/user.admin.inc b/modules/user/user.admin.inc index 08f9b1ba5..b53f9b927 100644 --- a/modules/user/user.admin.inc +++ b/modules/user/user.admin.inc @@ -33,10 +33,7 @@ function user_admin($callback_arg = '') { * @see user_filter_form_submit() */ function user_filter_form() { - if (!isset($_SESSION['user_overview_filter'])) { - drupal_set_session('user_overview_filter', array()); - } - $session = &$_SESSION['user_overview_filter']; + $session = isset($_SESSION['user_overview_filter']) ? $_SESSION['user_overview_filter'] : array(); $filters = user_filters(); $i = 0; @@ -103,9 +100,6 @@ function user_filter_form_submit($form, &$form_state) { // Merge an array of arrays into one if necessary. $options = $filter == 'permission' ? call_user_func_array('array_merge', $filters[$filter]['options']) : $filters[$filter]['options']; if (isset($options[$form_state['values'][$filter]])) { - if (!isset($_SESSION['user_overview_filter'])) { - drupal_set_session('user_overview_filter', array()); - } $_SESSION['user_overview_filter'][] = array($filter, $form_state['values'][$filter]); } } @@ -114,7 +108,7 @@ function user_filter_form_submit($form, &$form_state) { array_pop($_SESSION['user_overview_filter']); break; case t('Reset'): - drupal_set_session('user_overview_filter', array()); + $_SESSION['user_overview_filter'] = array(); break; case t('Update'): return; diff --git a/modules/user/user.module b/modules/user/user.module index 460d6858e..089f121ab 100644 --- a/modules/user/user.module +++ b/modules/user/user.module @@ -1715,10 +1715,12 @@ function user_authenticate_finalize(&$edit) { ->fields(array('login' => $user->login)) ->condition('uid', $user->uid) ->execute(); + // Regenerate the session ID to prevent against session fixation attacks. // This is called before hook_user in case one of those functions fails // or incorrectly does a redirect which would leave the old session in place. drupal_session_regenerate(); + user_module_invoke('login', $edit, $user); } @@ -2482,7 +2484,7 @@ function user_build_filter_query(SelectQuery $query) { $filters = user_filters(); // Extend Query with filter conditions. - foreach ($_SESSION['user_overview_filter'] as $filter) { + foreach (isset($_SESSION['user_overview_filter']) ? $_SESSION['user_overview_filter'] : array() as $filter) { list($key, $value) = $filter; // This checks to see if this permission filter is an enabled permission for // the authenticated role. If so, then all users would be listed, and we can |