Index: includes/common.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/common.inc,v retrieving revision 1.611.2.25 diff -u -F '^f' -r1.611.2.25 common.inc --- includes/common.inc 16 Sep 2009 17:29:09 -0000 1.611.2.25 +++ includes/common.inc 3 Mar 2010 23:59:25 -0000 @@ -302,11 +302,22 @@ function drupal_get_destination() { * @see 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, $query, $fragment, TRUE); Index: includes/locale.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/locale.inc,v retrieving revision 1.105.2.5 diff -u -F '^f' -r1.105.2.5 locale.inc --- includes/locale.inc 17 Dec 2007 01:53:52 -0000 1.105.2.5 +++ includes/locale.inc 3 Mar 2010 23:59:25 -0000 @@ -41,6 +41,9 @@ function _locale_admin_manage_screen() { $options = array(); $form['name'] = array('#tree' => TRUE); foreach ($languages['name'] as $key => $lang) { + // Language code should contain no markup, but is emitted + // by radio and checkbox options. + $key = check_plain($key); $options[$key] = ''; $status = db_fetch_object(db_query("SELECT isdefault, enabled FROM {locales_meta} WHERE locale = '%s'", $key)); if ($status->enabled) { @@ -97,6 +100,14 @@ function theme_locale_admin_manage_scree return $output; } +function _locale_admin_manage_screen_validate($form_id, $form_values) { + foreach ($form_values['name'] as $key => $value) { + if (preg_match('/["<>\']/', $value)) { + form_set_error('name][' . $key, t('The characters <, >, " and \' are not allowed in the language name in English field.')); + } + } +} + /** * Process locale admin manager form submissions. */ @@ -184,12 +195,22 @@ function locale_add_language_form_valida form_set_error(t('The language %language (%code) already exists.', array('%language' => $form_values['langname'], '%code' => $form_values['langcode']))); } + // If we are adding a non-custom language, check for a valid langcode. if (!isset($form_values['langname'])) { $isocodes = _locale_get_iso639_list(); if (!isset($isocodes[$form_values['langcode']])) { form_set_error('langcode', t('Invalid language code.')); } } + // Otherwise, check for invlaid characters + else { + if (preg_match('/["<>\']/', $form_values['langcode'])) { + form_set_error('langcode', t('The characters <, >, " and \' are not allowed in the language code field.')); + } + if (preg_match('/["<>\']/', $form_values['langname'])) { + form_set_error('langname', t('The characters <, >, " and \' are not allowed in the language name in English field.')); + } + } } /** @@ -331,8 +352,14 @@ function _locale_export_po_form_submit($ function _locale_string_seek_form() { // Get *all* languages set up $languages = locale_supported_languages(FALSE, TRUE); - asort($languages['name']); unset($languages['name']['en']); - $languages['name'] = array_map('check_plain', $languages['name']); + unset($languages['name']['en']); + // Sanitize the values to be used in radios. + $languages_name = array(); + foreach ($languages['name'] as $key => $value) { + $languages_name[check_plain($key)] = check_plain($value); + } + $languages['name'] = $languages_name; + asort($languages['name']); // Present edit form preserving previous user settings $query = _locale_string_seek_query(); Index: includes/session.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/session.inc,v retrieving revision 1.37.2.7 diff -u -F '^f' -r1.37.2.7 session.inc --- includes/session.inc 11 Dec 2008 00:23:01 -0000 1.37.2.7 +++ includes/session.inc 3 Mar 2010 23:59:25 -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: modules/locale/locale.install =================================================================== RCS file: /cvs/drupal/drupal/modules/locale/locale.install,v retrieving revision 1.7 diff -u -F '^f' -r1.7 locale.install --- modules/locale/locale.install 14 Nov 2006 06:20:40 -0000 1.7 +++ modules/locale/locale.install 3 Mar 2010 23:59:25 -0000 @@ -85,3 +85,23 @@ function locale_uninstall() { db_query('DROP TABLE {locales_source}'); db_query('DROP TABLE {locales_target}'); } + +/** + * Neutralize unsafe language names in the database. + */ +function locale_update_1() { + $ret = array(); + $matches = db_result(db_query("SELECT 1 FROM {locales_meta} WHERE name LIKE '%<%' OR name LIKE '%>%'")); + if ($matches) { + $ret[] = update_sql("UPDATE {locales_meta} SET name = REPLACE(name, '<', '')"); + $ret[] = update_sql("UPDATE {locales_meta} SET name = REPLACE(name, '>', '')"); + drupal_set_message('The language name in English 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 {locales_meta} WHERE locale LIKE '%<%' OR locale LIKE '%>%' OR locale LIKE '%\"%' OR locale 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; +} Index: modules/locale/locale.module =================================================================== RCS file: /cvs/drupal/drupal/modules/locale/locale.module,v retrieving revision 1.155.2.1 diff -u -F '^f' -r1.155.2.1 locale.module --- modules/locale/locale.module 9 Jul 2008 21:48:42 -0000 1.155.2.1 +++ modules/locale/locale.module 3 Mar 2010 23:59:25 -0000 @@ -137,15 +137,17 @@ function locale_user($type, $edit, &$use if ($user->language == '') { $user->language = key($languages['name']); } - $languages['name'] = array_map('check_plain', array_map('t', $languages['name'])); + foreach (array_map('t', $languages['name']) as $key => $value) { + $languages_name[check_plain($key)] = check_plain($value); + } $form['locale'] = array('#type' => 'fieldset', '#title' => t('Interface language settings'), '#weight' => 1, ); $form['locale']['language'] = array('#type' => 'radios', '#title' => t('Language'), - '#default_value' => $user->language, - '#options' => $languages['name'], + '#default_value' => check_plain($user->language), + '#options' => $languages_name, '#description' => t('Selecting a different locale will change the interface language of the site.'), ); return $form;