Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.1175
diff -u -p -r1.1175 common.inc
--- includes/common.inc	5 Jun 2010 13:18:09 -0000	1.1175
+++ includes/common.inc	8 Jun 2010 13:12:17 -0000
@@ -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 external 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'];
@@ -2091,7 +2092,16 @@ function url($path = NULL, array $option
 }
 
 /**
- * Return TRUE if a path is external (e.g. http://example.com).
+ * Return TRUE if a path is external to Drupal (e.g. http://example.com).
+ *
+ * If a path cannot be assessed by Drupal's menu handler, then we must
+ * treat it as potentially insecure.
+ *
+ * @param $path
+ *   The internal path or external URL being linked to, such as "node/34" or
+ *   "http://example.com/foo".
+ * @return 
+ *   Boolean TRUE or FALSE, where TRUE indicates an external path.
  */
 function url_is_external($path) {
   $colonpos = strpos($path, ':');
Index: modules/simpletest/tests/common.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/tests/common.test,v
retrieving revision 1.112
diff -u -p -r1.112 common.test
--- modules/simpletest/tests/common.test	18 May 2010 06:59:46 -0000	1.112
+++ modules/simpletest/tests/common.test	8 Jun 2010 13:12:21 -0000
@@ -196,8 +196,13 @@ class CommonURLUnitTest extends DrupalWe
     );
     $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 external 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,8 +227,12 @@ class CommonURLUnitTest extends DrupalWe
     // 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.'));
+  }
+  
   /**
    * Test url() with/without query, with/without fragment, absolute on/off and
    * assert all that works when clean URLs are on and off.
Index: modules/system/system.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.install,v
retrieving revision 1.471
diff -u -p -r1.471 system.install
--- modules/system/system.install	3 Jun 2010 13:20:05 -0000	1.471
+++ modules/system/system.install	8 Jun 2010 13:12:25 -0000
@@ -364,8 +364,8 @@ function system_requirements($phase) {
   if ($phase == 'update') {
     $files = system_rebuild_module_data();
     foreach ($files as $module => $file) {
-      // Ignore disabled modules.
-      if (!$file->status) {
+      // Ignore disabled modules and install profiles.
+      if (!$file->status || substr($file->filename, -8, 8) == '.profile') {
         continue;
       }
       // Check the module's PHP version.
Index: modules/system/system.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.test,v
retrieving revision 1.125
diff -u -p -r1.125 system.test
--- modules/system/system.test	26 May 2010 07:31:47 -0000	1.125
+++ modules/system/system.test	8 Jun 2010 13:12:28 -0000
@@ -1740,6 +1740,31 @@ class UpdateScriptFunctionalTest extends
   }
 
   /**
+   * Tests the detection of requirements for the update script to proceed.
+   */
+  function testUpdateRequirements() {
+    $this->drupalLogin($this->update_user);
+    $this->drupalGet($this->update_url, array('external' => TRUE));
+    $this->assertResponse(200);
+    // Test if disabling a module that another enabled module depends on will
+    // prevent the update from proceeding.
+    module_disable(array('block'), FALSE);
+    $this->assertFalse(module_exists('block'), t('Block module is disabled.'));
+    $this->assertTrue(module_exists('dashboard'), t('Dashboard module is enabled.'));
+    $this->drupalGet($this->update_url, array('external' => TRUE));
+    $this->assertText(t('Unresolved dependency'), t('The update process cannot proceed when a module dependency is not enabled.'));
+
+    // Test if modules required by the current install profile are not required
+    // to be enabled for an update to proceed.
+    module_enable(array('block'));
+    $this->assertTrue(module_exists('block'), t('Block module is enabled.'));
+    module_disable(array('overlay'));
+    $this->assertFalse(module_exists('overlay'), t('Overlay module is disabled.'));
+    $this->drupalGet($this->update_url, array('external' => TRUE));
+    $this->assertNoText(t('Unresolved dependency'), t('The update process can proceed when modules from the install profile are disabled.'));
+  }
+
+  /**
    * Tests the effect of using the update script on the theme system.
    */
   function testThemeSystem() {
