summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerhard Killesreiter2007-07-26 19:17:25 (GMT)
committerGerhard Killesreiter2007-07-26 19:17:25 (GMT)
commitb60bac779f768e6cae6a587d3f64ad7f5e910150 (patch)
treee8152be9dd5ad82fc4114da5c4e83adc0b5e1ba7
parent6f17c8d29bc529fabb6ccf5ecd650e209007c856 (diff)
Drupal 4.7.7
-rw-r--r--CHANGELOG.txt5
-rw-r--r--includes/bootstrap.inc20
-rw-r--r--includes/common.inc2
-rw-r--r--modules/poll.module4
-rw-r--r--modules/profile.module8
-rw-r--r--modules/user.module2
-rw-r--r--sites/default/settings.php4
7 files changed, 30 insertions, 15 deletions
diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 4838061..38d527f 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,4 +1,9 @@
// $Id$
+
+Drupal 4.7.7, 2007-07-26
+------------------------
+- fixed security issue (XSS), see SA-2007-018
+
Drupal 4.7.6, 2007-01-29
------------------------
- fixed security issue (code execution), see SA-2007-005
diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc
index ae6f769..c322f54 100644
--- a/includes/bootstrap.inc
+++ b/includes/bootstrap.inc
@@ -116,7 +116,7 @@ function conf_path() {
}
$confdir = 'sites';
- $uri = explode('/', $_SERVER['PHP_SELF'] ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_FILENAME']);
+ $uri = explode('/', $_SERVER['SCRIPT_NAME'] ? $_SERVER['SCRIPT_NAME'] : $_SERVER['SCRIPT_FILENAME']);
$server = explode('.', implode('.', array_reverse(explode(':', rtrim($_SERVER['HTTP_HOST'], '.')))));
for ($i = count($uri) - 1; $i > 0; $i--) {
for ($j = count($server); $j > 0; $j--) {
@@ -166,8 +166,14 @@ function conf_init() {
else {
// Create base URL
$base_root = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 'https' : 'http';
- $base_url = $base_root .= '://'. $_SERVER['HTTP_HOST'];
- if ($dir = trim(dirname($_SERVER['PHP_SELF']), '\,/')) {
+
+ // As $_SERVER['HTTP_HOST'] is user input, ensure it only contains
+ // characters allowed in hostnames.
+ $base_url = $base_root .= '://'. preg_replace('/[^a-z0-9-:._]/i', '', $_SERVER['HTTP_HOST']);
+
+ // $_SERVER['SCRIPT_NAME'] can, in contrast to $_SERVER['PHP_SELF'], not
+ // be modified by a visitor.
+ if ($dir = trim(dirname($_SERVER['SCRIPT_NAME']), '\,/')) {
$base_path = "/$dir";
$base_url .= $base_path;
$base_path .= '/';
@@ -495,7 +501,7 @@ function drupal_load($type, $name) {
/**
* Set HTTP headers in preparation for a page response.
- *
+ *
* The general approach here is that anonymous users can keep a local cache of
* the page, but must revalidate it on every request. Then, they are given a
* '304 Not Modified' response as long as they stay logged out and the page
@@ -536,7 +542,7 @@ function drupal_page_header() {
// The following headers force validation of cache
header("Expires: Sun, 19 Nov 1978 05:00:00 GMT");
header("Cache-Control: must-revalidate");
-
+
// Determine if the browser accepts gzipped data.
if (@strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') === false && function_exists('gzencode')) {
// Strip the gzip header and run uncompress.
@@ -620,10 +626,10 @@ function request_uri() {
}
else {
if (isset($_SERVER['argv'])) {
- $uri = $_SERVER['PHP_SELF'] .'?'. $_SERVER['argv'][0];
+ $uri = $_SERVER['SCRIPT_NAME'] .'?'. $_SERVER['argv'][0];
}
else {
- $uri = $_SERVER['PHP_SELF'] .'?'. $_SERVER['QUERY_STRING'];
+ $uri = $_SERVER['SCRIPT_NAME'] .'?'. $_SERVER['QUERY_STRING'];
}
}
diff --git a/includes/common.inc b/includes/common.inc
index 5390a85..f307ea8 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -502,7 +502,7 @@ function error_handler($errno, $message, $filename, $line) {
$entry = $types[$errno] .': '. $message .' in '. $filename .' on line '. $line .'.';
// Force display of error messages in update.php
- if (variable_get('error_level', 1) == 1 || strstr($_SERVER['PHP_SELF'], 'update.php')) {
+ if (variable_get('error_level', 1) == 1 || strstr($_SERVER['SCRIPT_NAME'], 'update.php')) {
drupal_set_message($entry, 'error');
}
diff --git a/modules/poll.module b/modules/poll.module
index e93d02c..a076105 100644
--- a/modules/poll.module
+++ b/modules/poll.module
@@ -282,7 +282,9 @@ function poll_teaser($node) {
$teaser = NULL;
if (is_array($node->choice)) {
foreach ($node->choice as $k => $choice) {
- $teaser .= '* '. $choice['chtext'] .'\n';
+ if ($choice['chtext'] != '') {
+ $teaser .= '* '. check_plain($choice['chtext']) ."\n";
+ }
}
}
return $teaser;
diff --git a/modules/profile.module b/modules/profile.module
index 8f89cd2..bb1e705 100644
--- a/modules/profile.module
+++ b/modules/profile.module
@@ -94,7 +94,7 @@ function profile_block($op = 'list', $delta = 0, $edit = array()) {
$fields = array();
$result = db_query('SELECT name, title, weight, visibility FROM {profile_fields} WHERE visibility IN (%d, %d) ORDER BY weight', PROFILE_PUBLIC, PROFILE_PUBLIC_LISTINGS);
while ($record = db_fetch_object($result)) {
- $fields[$record->name] = $record->title;
+ $fields[$record->name] = check_plain($record->title);
}
$fields['user_profile'] = t('Link to full user profile');
$form['profile_block_author_fields'] = array('#type' => 'checkboxes',
@@ -373,7 +373,7 @@ function profile_admin_overview() {
$result = db_query('SELECT * FROM {profile_fields} ORDER BY category, weight');
$rows = array();
while ($field = db_fetch_object($result)) {
- $rows[] = array(check_plain($field->title), $field->name, _profile_field_types($field->type), $field->category, l(t('edit'), "admin/settings/profile/edit/$field->fid"), l(t('delete'), "admin/settings/profile/delete/$field->fid"));
+ $rows[] = array(check_plain($field->title), check_plain($field->name), _profile_field_types($field->type), $field->category, l(t('edit'), "admin/settings/profile/edit/$field->fid"), l(t('delete'), "admin/settings/profile/delete/$field->fid"));
}
if (count($rows) == 0) {
$rows[] = array(array('data' => t('No fields defined.'), 'colspan' => '6'));
@@ -623,7 +623,7 @@ function profile_form_profile($edit, $user, $category) {
while ($field = db_fetch_object($result)) {
$category = $field->category;
if (!isset($fields[$category])) {
- $fields[$category] = array('#type' => 'fieldset', '#title' => $category, '#weight' => $w++);
+ $fields[$category] = array('#type' => 'fieldset', '#title' => check_plain($category), '#weight' => $w++);
}
switch ($field->type) {
case 'textfield':
@@ -748,7 +748,7 @@ function theme_profile_block($account, $fields = array()) {
$output .= "<p>$field->value</p>\n";
}
else {
- $output .= "<p><strong>$field->title</strong><br />$field->value</p>\n";
+ $output .= '<p><strong>'. check_plain($field->title) ."</strong><br />$field->value</p>\n";
}
}
}
diff --git a/modules/user.module b/modules/user.module
index 51722cb..4c5ca29 100644
--- a/modules/user.module
+++ b/modules/user.module
@@ -699,7 +699,7 @@ function theme_user_profile($account, $fields) {
$output .= theme('user_picture', $account);
foreach ($fields as $category => $items) {
if (strlen($category) > 0) {
- $output .= '<h2 class="title">'. $category .'</h2>';
+ $output .= '<h2 class="title">'. check_plain($category) .'</h2>';
}
$output .= '<dl>';
foreach ($items as $item) {
diff --git a/sites/default/settings.php b/sites/default/settings.php
index 02e3bb7..998bde7 100644
--- a/sites/default/settings.php
+++ b/sites/default/settings.php
@@ -138,7 +138,9 @@ if (isset($_SERVER['HTTP_HOST'])) {
// Per RFC 2109, cookie domains must contain at least one dot other than the
// first. For hosts such as 'localhost', we don't set a cookie domain.
if (count(explode('.', $domain)) > 2) {
- ini_set('session.cookie_domain', $domain);
+ // We need to use escaping because $_SERVER['HTTP_HOST'] can be modified
+ // by a visitor.
+ ini_set('session.cookie_domain', check_plain($domain));
}
}