--- 736172-drupal-goto-same-domain-5.patch 2012-10-19 00:05:08.000000000 -0400 +++ 736172-drupal-goto-same-domain-6.patch 2012-10-23 17:14:14.353324620 -0400 @@ -1,33 +1,38 @@ diff --git a/core/includes/common.inc b/core/includes/common.inc -index 0f252ca..5d025c5 100644 +index 6800fa5..446580e 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc -@@ -683,8 +683,9 @@ function drupal_encode_path($path) { +@@ -683,8 +683,11 @@ function drupal_encode_path($path) { */ function drupal_goto($path = '', array $options = array(), $http_response_code = 302) { // A destination in $_GET always overrides the function arguments. - // We do not allow absolute URLs to be passed via $_GET, as this can be an attack vector. - if (isset($_GET['destination']) && !url_is_external($_GET['destination'])) { -+ // We do not allow absolute URLs to be passed via $_GET, as this can be an attack vector, with the following exception: -+ // - absolute URLs that point to this site (i.e. same base URL and base path) are allowed ++ // We do not allow absolute URLs to be passed via $_GET, as this can be an ++ // attack vector, with the following exception: ++ // - absolute URLs that point to this site (i.e. same base URL and ++ // base path) are allowed + if (isset($_GET['destination']) && (!url_is_external($_GET['destination']) || _external_url_is_local($_GET['destination']))) { $destination = drupal_parse_url($_GET['destination']); $path = $destination['path']; $options['query'] = $destination['query']; -@@ -707,6 +708,22 @@ function drupal_goto($path = '', array $options = array(), $http_response_code = +@@ -707,6 +710,25 @@ function drupal_goto($path = '', array $options = array(), $http_response_code = } /** -+ * Helper function for determining if an external URL points to this Drupal installation. ++ * Determines if an external URL points to this Drupal installation. ++ * ++ * @param $url ++ * A string containing an external URL, such as "http://example.com/foo". + * + * @return -+ * TRUE if the URL has the same domain and base path ++ * TRUE if the URL has the same domain and base path. + */ +function _external_url_is_local($url) { + $url_parts = parse_url($url); + $base_host = parse_url($GLOBALS['base_url'], PHP_URL_HOST); + -+ // When comparing base path's, we need a trailing slash to make sure a ++ // When comparing base paths, we need a trailing slash to make sure a + // partial URL match isn't occuring. Since base_path() always returns with + // a trailing slash, we don't need to add the trailing slash here. + return ($url_parts['host'] == $base_host && stripos($url_parts['path'], base_path()) === 0);