summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil Drumm2010-03-04 00:16:02 +0000
committerNeil Drumm2010-03-04 00:16:02 +0000
commitf63e56caf1c0ac256448fd1127b9dfeb9cd4931f (patch)
tree8bb44f7d886fadf37f5fffd0c84a770771283156
parent65617aa9b846269c075ee18bc577cacd42a31794 (diff)
Drupal 5.225.22
-rw-r--r--CHANGELOG.txt4
-rw-r--r--includes/common.inc15
-rw-r--r--includes/locale.inc31
-rw-r--r--includes/session.inc8
-rw-r--r--modules/locale/locale.install20
-rw-r--r--modules/locale/locale.module8
-rw-r--r--modules/system/system.module2
7 files changed, 76 insertions, 12 deletions
diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 09ec8d9..0e80484 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,7 +1,9 @@
// $Id$
-Drupal 5.22, xxxx-xx-xx
+Drupal 5.22, 2010-03-03
-----------------------
+- Fixed security issues (Open redirection, Locale module cross site scripting,
+ Blocked user session regeneration), see SA-CORE-2010-001.
Drupal 5.21, 2009-12-16
-----------------------
diff --git a/includes/common.inc b/includes/common.inc
index a7f2674..e7b9bf5 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -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);
diff --git a/includes/locale.inc b/includes/locale.inc
index 2b0e594..0963d20 100644
--- a/includes/locale.inc
+++ b/includes/locale.inc
@@ -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_screen($form) {
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 &lt;, &gt;, " 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_validate($form_id, $form_values) {
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 &lt;, &gt;, " and \' are not allowed in the language code field.'));
+ }
+ if (preg_match('/["<>\']/', $form_values['langname'])) {
+ form_set_error('langname', t('The characters &lt;, &gt;, " and \' are not allowed in the language name in English field.'));
+ }
+ }
}
/**
@@ -331,8 +352,14 @@ function _locale_export_po_form_submit($form_id, $form_values) {
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();
diff --git a/includes/session.inc b/includes/session.inc
index 4037d84..df768b9 100644
--- a/includes/session.inc
+++ b/includes/session.inc
@@ -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);
diff --git a/modules/locale/locale.install b/modules/locale/locale.install
index ecba859..0247065 100644
--- a/modules/locale/locale.install
+++ b/modules/locale/locale.install
@@ -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 <a href="'. url('admin/settings/language') .'">Languages</a> 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 <a href="'. url('admin/settings/language') .'">Languages</a> page. These must be fixed manually.', 'error');
+ }
+ return $ret;
+}
diff --git a/modules/locale/locale.module b/modules/locale/locale.module
index 9c72101..cf4d41e 100644
--- a/modules/locale/locale.module
+++ b/modules/locale/locale.module
@@ -137,15 +137,17 @@ function locale_user($type, $edit, &$user, $category = NULL) {
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;
diff --git a/modules/system/system.module b/modules/system/system.module
index ee0dbfb..30d3861 100644
--- a/modules/system/system.module
+++ b/modules/system/system.module
@@ -6,7 +6,7 @@
* Configuration system that lets administrators modify the workings of the site.
*/
-define('VERSION', '5.22-dev');
+define('VERSION', '5.22');
/**
* Implementation of hook_help().