diff options
-rw-r--r-- | includes/common.inc | 3 | ||||
-rw-r--r-- | modules/simpletest/tests/common.test | 11 |
2 files changed, 12 insertions, 2 deletions
diff --git a/includes/common.inc b/includes/common.inc index a170ee1bb..0cac24553 100644 --- a/includes/common.inc +++ b/includes/common.inc @@ -659,7 +659,8 @@ 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. - if (isset($_GET['destination'])) { + // 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'])) { $destination = drupal_parse_url($_GET['destination']); $path = $destination['path']; $options['query'] = $destination['query']; diff --git a/modules/simpletest/tests/common.test b/modules/simpletest/tests/common.test index 53fb5704f..f374cf04b 100644 --- a/modules/simpletest/tests/common.test +++ b/modules/simpletest/tests/common.test @@ -196,8 +196,13 @@ class CommonURLUnitTest extends DrupalWebTestCase { ); $this->assertEqual(drupal_parse_url($url), $result, t('Absolute URL parsed correctly.')); - // External URL. + // External URL testing. $url = 'http://drupal.org/foo/bar?foo=bar&bar=baz&baz#foo'; + + // Test that drupal can recognize an absolute URL. Used to prevent attack vectors. + $this->assertTrue(url_is_external($url), t('Correctly identified an external URL.')); + + // Test the parsing of absolute URLs. $result = array( 'path' => 'http://drupal.org/foo/bar', 'query' => array('foo' => 'bar', 'bar' => 'baz', 'baz' => ''), @@ -222,6 +227,10 @@ class CommonURLUnitTest extends DrupalWebTestCase { // Non-clean URLs #3: URL generated by url() on non-Apache webserver. $url = 'index.php?q=foo/bar&bar=baz#foo'; $this->assertEqual(drupal_parse_url($url), $result, t('Relative URL on non-Apache webserver with clean URLs disabled parsed correctly.')); + + // Test that drupal_parse_url() does not allow spoofing a URL to force a malicious redirect. + $parts = drupal_parse_url('forged:http://cwe.mitre.org/data/definitions/601.html'); + $this->assertFalse(valid_url($parts['path'], TRUE), t('drupal_parse_url() correctly parsed a forged URL.')); } /** |