Index: includes/common.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/common.inc,v retrieving revision 1.756.2.74 diff -u -p -r1.756.2.74 common.inc --- includes/common.inc 16 Dec 2009 20:47:10 -0000 1.756.2.74 +++ includes/common.inc 3 Mar 2010 23:47:20 -0000 @@ -311,11 +311,21 @@ function drupal_get_destination() { */ function drupal_goto($path = '', $query = NULL, $fragment = NULL, $http_response_code = 302) { + $destination = FALSE; if (isset($_REQUEST['destination'])) { - extract(parse_url(urldecode($_REQUEST['destination']))); + $destination = $_REQUEST['destination']; } else if (isset($_REQUEST['edit']['destination'])) { - extract(parse_url(urldecode($_REQUEST['edit']['destination']))); + $destination = $_REQUEST['edit']['destination']; + } + + if ($destination) { + // Do not redirect to an absolute URL originating from user input. + $colonpos = strpos($destination, ':'); + $absolute = ($colonpos !== FALSE && !preg_match('![/?#]!', substr($destination, 0, $colonpos))); + if (!$absolute) { + extract(parse_url(urldecode($destination))); + } } $url = url($path, array('query' => $query, 'fragment' => $fragment, 'absolute' => TRUE)); Index: includes/locale.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/locale.inc,v retrieving revision 1.174.2.10 diff -u -p -r1.174.2.10 locale.inc --- includes/locale.inc 15 Sep 2009 10:40:26 -0000 1.174.2.10 +++ includes/locale.inc 3 Mar 2010 23:47:20 -0000 @@ -34,6 +34,9 @@ function locale_languages_overview_form( $options = array(); $form['weight'] = array('#tree' => TRUE); foreach ($languages as $langcode => $language) { + // Language code should contain no markup, but is emitted + // by radio and checkbox options. + $langcode = check_plain($langcode); $options[$langcode] = ''; if ($language->enabled) { @@ -335,6 +338,17 @@ function locale_languages_predefined_for * Validate the language editing form. Reused for custom language addition too. */ function locale_languages_edit_form_validate($form, &$form_state) { + // Validate that the name, native, and langcode variables are safe. + if (preg_match('/["<>\']/', $form_state['values']['langcode'])) { + form_set_error('langcode', t('The characters <, >, " and \' are not allowed in the language code field.')); + } + if (preg_match('/["<>\']/', $form_state['values']['name'])) { + form_set_error('name', t('The characters <, >, " and \' are not allowed in the language name in English field.')); + } + if (preg_match('/["<>\']/', $form_state['values']['native'])) { + form_set_error('native', t('The characters <, >, " and \' are not allowed in the native language name field.')); + } + if (!empty($form_state['values']['domain']) && !empty($form_state['values']['prefix'])) { form_set_error('prefix', t('Domain and path prefix values should not be set at the same time.')); } @@ -536,8 +550,13 @@ function locale_translate_seek_screen() */ function locale_translate_seek_form() { // Get all languages, except English - $languages = locale_language_list('name', TRUE); - unset($languages['en']); + $raw_languages = locale_language_list('name', TRUE); + unset($raw_languages['en']); + // Sanitize the values to be used in radios. + $languages = array(); + foreach ($raw_languages as $key => $value) { + $languages[check_plain($key)] = check_plain($value); + } // Present edit form preserving previous user settings $query = _locale_translate_seek_query(); Index: includes/session.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/session.inc,v retrieving revision 1.44.2.6 diff -u -p -r1.44.2.6 session.inc --- includes/session.inc 11 Dec 2008 00:29:34 -0000 1.44.2.6 +++ includes/session.inc 3 Mar 2010 23:47:20 -0000 @@ -31,8 +31,9 @@ function sess_read($key) { // Otherwise, if the session is still active, we have a record of the client's session in the database. $user = db_fetch_object(db_query("SELECT u.*, s.* FROM {users} u INNER JOIN {sessions} s ON u.uid = s.uid WHERE s.sid = '%s'", $key)); - // We found the client's session record and they are an authenticated user - if ($user && $user->uid > 0) { + // We found the client's session record and they are an authenticated, + // active user. + if ($user && $user->uid > 0 && $user->status == 1) { // This is done to unserialize the data member of $user $user = drupal_unpack($user); @@ -44,7 +45,8 @@ function sess_read($key) { $user->roles[$role->rid] = $role->name; } } - // We didn't find the client's record (session has expired), or they are an anonymous user. + // We didn't find the client's record (session has expired), or they are + // blocked, or they are an anonymous user. else { $session = isset($user->session) ? $user->session : ''; $user = drupal_anonymous_user($session); Index: includes/theme.maintenance.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/theme.maintenance.inc,v retrieving revision 1.10.2.1 diff -u -p -r1.10.2.1 theme.maintenance.inc --- includes/theme.maintenance.inc 10 Aug 2009 11:11:59 -0000 1.10.2.1 +++ includes/theme.maintenance.inc 3 Mar 2010 23:47:20 -0000 @@ -125,9 +125,9 @@ function theme_install_page($content) { $title = count($messages['error']) > 1 ? st('The following errors must be resolved before you can continue the installation process') : st('The following error must be resolved before you can continue the installation process'); $variables['messages'] .= '

'. $title .':

'; $variables['messages'] .= theme('status_messages', 'error'); - $variables['content'] .= '

'. st('Please check the error messages and try again.', array('!url' => request_uri())) .'

'; + $variables['content'] .= '

'. st('Please check the error messages and try again.', array('!url' => check_url(request_uri()))) .'

'; } - + // Special handling of warning messages if (isset($messages['warning'])) { $title = count($messages['warning']) > 1 ? st('The following installation warnings should be carefully reviewed') : st('The following installation warning should be carefully reviewed'); Index: modules/locale/locale.install =================================================================== RCS file: /cvs/drupal/drupal/modules/locale/locale.install,v retrieving revision 1.27.2.1 diff -u -p -r1.27.2.1 locale.install --- modules/locale/locale.install 6 Jan 2009 15:46:37 -0000 1.27.2.1 +++ modules/locale/locale.install 3 Mar 2010 23:47:20 -0000 @@ -202,6 +202,26 @@ function locale_update_6005() { } /** + * Neutralize unsafe language names in the database. + */ +function locale_update_6006() { + $ret = array(); + $matches = db_result(db_query("SELECT 1 FROM {languages} WHERE native LIKE '%<%' OR native LIKE '%>%' OR name LIKE '%<%' OR name LIKE '%>%'")); + if ($matches) { + $ret[] = update_sql("UPDATE {languages} SET name = REPLACE(name, '<', ''), native = REPLACE(native, '<', '')"); + $ret[] = update_sql("UPDATE {languages} SET name = REPLACE(name, '>', ''), native = REPLACE(native, '>', '')"); + drupal_set_message('The language name in English and the native language name values of all the existing custom languages of your site have been sanitized for security purposes. Visit the Languages page to check these and fix them if necessary.', 'warning'); + } + // Check if some langcode values contain potentially dangerous characters and + // warn the user if so. These are not fixed since they are referenced in other + // tables (e.g. {node}). + if (db_result(db_query("SELECT 1 FROM {languages} WHERE language LIKE '%<%' OR language LIKE '%>%' OR language LIKE '%\"%' OR language LIKE '%\\\\\%'"))) { + drupal_set_message('Some of your custom language code values contain invalid characters. You should examine the Languages page. These must be fixed manually.', 'error'); + } + return $ret; +} + +/** * @} End of "defgroup updates-5.x-to-6.x" */ Index: modules/locale/locale.module =================================================================== RCS file: /cvs/drupal/drupal/modules/locale/locale.module,v retrieving revision 1.212.2.6 diff -u -p -r1.212.2.6 locale.module --- modules/locale/locale.module 25 Feb 2009 11:47:37 -0000 1.212.2.6 +++ modules/locale/locale.module 3 Mar 2010 23:47:20 -0000 @@ -215,7 +215,7 @@ function locale_user($type, $edit, &$use $names = array(); foreach ($languages as $langcode => $item) { $name = t($item->name); - $names[$langcode] = $name . ($item->native != $name ? ' ('. $item->native .')' : ''); + $names[check_plain($langcode)] = check_plain($name . ($item->native != $name ? ' ('. $item->native .')' : '')); } $form['locale'] = array( '#type' => 'fieldset', @@ -228,7 +228,7 @@ function locale_user($type, $edit, &$use $form['locale']['language'] = array( '#type' => (count($names) <= 5 ? 'radios' : 'select'), '#title' => t('Language'), - '#default_value' => $user_preferred_language->language, + '#default_value' => check_plain($user_preferred_language->language), '#options' => $names, '#description' => ($mode == LANGUAGE_NEGOTIATION_PATH) ? t("This account's default language for e-mails, and preferred language for site presentation.") : t("This account's default language for e-mails."), );