summaryrefslogtreecommitdiff
path: root/includes
diff options
context:
space:
mode:
authorDavid Rothstein <drothstein@gmail.com>2016-02-24 14:26:52 -0500
committerDavid Rothstein <drothstein@gmail.com>2016-02-24 14:26:52 -0500
commit7b2dc7936e2566c711159f75634cbb60ddacb340 (patch)
tree9fdf1d34a03ec83b95a4fbcced22bb1b599f76d0 /includes
parentb8d9c44f83eca57039f648a0edb0f369f8d3e6b4 (diff)
downloadbrdo-7b2dc7936e2566c711159f75634cbb60ddacb340.tar.gz
brdo-7b2dc7936e2566c711159f75634cbb60ddacb340.tar.bz2
Drupal 7.43 (SA-CORE-2016-001) by agerard, Alan Evans, benjy, berdir, catch, Damien Tournoud, DamienMcKenna, Dave Cohen, Dave Reid, David_Rothstein, dsnopek, effulgentsia, FengWen, fgm, fnqgpc, greggles, Gábor Hojtsy, Juho Nurminen 2NS, klausi, larowlan, nagba, Pere Orga, plach, pwolanin, quicksketch, rickmanelius, scor, stefan.r, StryKaizer, YesCT
Diffstat (limited to 'includes')
-rw-r--r--includes/bootstrap.inc2
-rw-r--r--includes/common.inc37
-rw-r--r--includes/path.inc3
-rw-r--r--includes/xmlrpcs.inc8
4 files changed, 30 insertions, 20 deletions
diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc
index 3dde2740c..0428bd362 100644
--- a/includes/bootstrap.inc
+++ b/includes/bootstrap.inc
@@ -8,7 +8,7 @@
/**
* The current system version.
*/
-define('VERSION', '7.43-dev');
+define('VERSION', '7.43');
/**
* Core API compatibility.
diff --git a/includes/common.inc b/includes/common.inc
index 34fa9b962..c6303efad 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -688,6 +688,13 @@ function drupal_goto($path = '', array $options = array(), $http_response_code =
$options['fragment'] = $destination['fragment'];
}
+ // In some cases modules call drupal_goto(current_path()). We need to ensure
+ // that such a redirect is not to an external URL.
+ if ($path === current_path() && empty($options['external']) && url_is_external($path)) {
+ // Force url() to generate a non-external URL.
+ $options['external'] = FALSE;
+ }
+
drupal_alter('drupal_goto', $path, $options, $http_response_code);
// The 'Location' HTTP header must be absolute.
@@ -2220,20 +2227,8 @@ function url($path = NULL, array $options = array()) {
'prefix' => ''
);
- // A duplicate of the code from url_is_external() to avoid needing another
- // function call, since performance inside url() is critical.
if (!isset($options['external'])) {
- // Return an external link if $path contains an allowed absolute URL. Avoid
- // calling drupal_strip_dangerous_protocols() if there is any slash (/),
- // hash (#) or question_mark (?) before the colon (:) occurrence - if any -
- // as this would clearly mean it is not a URL. If the path starts with 2
- // slashes then it is always considered an external URL without an explicit
- // protocol part.
- $colonpos = strpos($path, ':');
- $options['external'] = (strpos($path, '//') === 0)
- || ($colonpos !== FALSE
- && !preg_match('![/?#]!', substr($path, 0, $colonpos))
- && drupal_strip_dangerous_protocols($path) == $path);
+ $options['external'] = url_is_external($path);
}
// Preserve the original path before altering or aliasing.
@@ -2353,12 +2348,18 @@ function url($path = NULL, array $options = array()) {
*/
function url_is_external($path) {
$colonpos = strpos($path, ':');
- // Avoid calling drupal_strip_dangerous_protocols() if there is any slash (/),
- // hash (#) or question_mark (?) before the colon (:) occurrence - if any - as
- // this would clearly mean it is not a URL. If the path starts with 2 slashes
- // then it is always considered an external URL without an explicit protocol
- // part.
+ // Some browsers treat \ as / so normalize to forward slashes.
+ $path = str_replace('\\', '/', $path);
+ // If the path starts with 2 slashes then it is always considered an external
+ // URL without an explicit protocol part.
return (strpos($path, '//') === 0)
+ // Leading control characters may be ignored or mishandled by browsers, so
+ // assume such a path may lead to an external location. The \p{C} character
+ // class matches all UTF-8 control, unassigned, and private characters.
+ || (preg_match('/^\p{C}/u', $path) !== 0)
+ // Avoid calling drupal_strip_dangerous_protocols() if there is any slash
+ // (/), hash (#) or question_mark (?) before the colon (:) occurrence - if
+ // any - as this would clearly mean it is not a URL.
|| ($colonpos !== FALSE
&& !preg_match('![/?#]!', substr($path, 0, $colonpos))
&& drupal_strip_dangerous_protocols($path) == $path);
diff --git a/includes/path.inc b/includes/path.inc
index 2e3571114..6bd48d306 100644
--- a/includes/path.inc
+++ b/includes/path.inc
@@ -347,7 +347,8 @@ function drupal_match_path($path, $patterns) {
* drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL) makes this function available.
*
* @return
- * The current Drupal URL path.
+ * The current Drupal URL path. The path is untrusted user input and must be
+ * treated as such.
*
* @see request_path()
*/
diff --git a/includes/xmlrpcs.inc b/includes/xmlrpcs.inc
index 8655c05b0..c334de159 100644
--- a/includes/xmlrpcs.inc
+++ b/includes/xmlrpcs.inc
@@ -264,6 +264,10 @@ function xmlrpc_server_call($xmlrpc_server, $methodname, $args) {
*/
function xmlrpc_server_multicall($methodcalls) {
// See http://www.xmlrpc.com/discuss/msgReader$1208
+ // To avoid multicall expansion attacks, limit the number of duplicate method
+ // calls allowed with a default of 1. Set to -1 for unlimited.
+ $duplicate_method_limit = variable_get('xmlrpc_multicall_duplicate_method_limit', 1);
+ $method_count = array();
$return = array();
$xmlrpc_server = xmlrpc_server_get();
foreach ($methodcalls as $call) {
@@ -273,10 +277,14 @@ function xmlrpc_server_multicall($methodcalls) {
$ok = FALSE;
}
$method = $call['methodName'];
+ $method_count[$method] = isset($method_count[$method]) ? $method_count[$method] + 1 : 1;
$params = $call['params'];
if ($method == 'system.multicall') {
$result = xmlrpc_error(-32600, t('Recursive calls to system.multicall are forbidden.'));
}
+ elseif ($duplicate_method_limit > 0 && $method_count[$method] > $duplicate_method_limit) {
+ $result = xmlrpc_error(-156579, t('Too many duplicate method calls in system.multicall.'));
+ }
elseif ($ok) {
$result = xmlrpc_server_call($xmlrpc_server, $method, $params);
}