diff --git a/core/includes/common.inc b/core/includes/common.inc
index 0dbabd8..293ed35 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -2,6 +2,7 @@
 
 use Drupal\Component\Utility\Crypt;
 use Drupal\Component\Utility\Json;
+use Drupal\Component\Utility\Settings;
 use Drupal\Component\Utility\SortArray;
 use Drupal\Component\Utility\String;
 use Drupal\Component\Utility\Tags;
@@ -269,11 +270,17 @@ function drupal_get_region_content($region = NULL, $delimiter = ' ') {
 function drupal_get_profile() {
   global $install_state;
 
-  if (isset($install_state['parameters']['profile'])) {
-    $profile = $install_state['parameters']['profile'];
+  if (drupal_installation_attempted()) {
+    // If the profile has been selected return it.
+    if (isset($install_state['parameters']['profile'])) {
+      $profile = $install_state['parameters']['profile'];
+    }
+    else {
+      $profile = '';
+    }
   }
   else {
-    $profile = variable_get('install_profile', 'standard');
+    $profile = Settings()->get('install_profile') ?: 'standard';
   }
 
   return $profile;
diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index 8e4b66e..d75d399 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -1234,6 +1234,14 @@ function install_settings_form_submit($form, &$form_state) {
     );
   }
 
+  // Remember the profile which was used.
+  $settings['settings'] = array(
+    'install_profile' => (object) array(
+      'value'    => $install_state['parameters']['profile'],
+      'required' => TRUE,
+    ),
+  );
+
   drupal_rewrite_settings($settings);
 
   // Add the config directories to settings.php.
@@ -1986,8 +1994,6 @@ function install_update_configuration_translations(&$install_state) {
  */
 function install_finished(&$install_state) {
   $profile = drupal_get_profile();
-  // Remember the profile which was used.
-  variable_set('install_profile', $profile);
 
   // Installation profiles are always loaded last.
   module_set_weight($profile, 1000);
diff --git a/core/includes/update.inc b/core/includes/update.inc
index 5e8ff4e..113dcdf 100644
--- a/core/includes/update.inc
+++ b/core/includes/update.inc
@@ -439,6 +439,23 @@ function update_prepare_d8_bootstrap() {
       }
     }
   }
+  // Moves install_profile from variable to settings. You can't do that in
+  // system.install because _system_rebuild_module_data() needs the profile
+  // directly. Check that it has not been set already. This is the case for
+  // Simpletest upgrade path tests.
+  if (!settings()->get('install_profile')) {
+    $old_variable = unserialize(Drupal::database()->query('SELECT value FROM {variable} WHERE name = :name', array(':name' => 'install_profile'))->fetchField());
+    $settings = array(
+      'settings' => array(
+        'install_profile' => (object) array(
+            'value'    => $old_variable,
+            'required' => TRUE,
+        ),
+      )
+    );
+    drupal_rewrite_settings($settings);
+  }
+
   // Now remove the cache override.
   $settings = settings()->getAll();
   unset($settings['cache']['default']);
diff --git a/core/modules/simpletest/lib/Drupal/simpletest/Tests/SimpleTestTest.php b/core/modules/simpletest/lib/Drupal/simpletest/Tests/SimpleTestTest.php
index 7aaf42f..645fd54 100644
--- a/core/modules/simpletest/lib/Drupal/simpletest/Tests/SimpleTestTest.php
+++ b/core/modules/simpletest/lib/Drupal/simpletest/Tests/SimpleTestTest.php
@@ -65,10 +65,6 @@ function testInternalBrowser() {
       )));
       $this->assertNoTitle('Foo');
 
-      global $base_url;
-      $this->drupalGet(url($base_url . '/core/install.php', array('external' => TRUE, 'absolute' => TRUE)));
-      $this->assertResponse(403, 'Cannot access install.php.');
-
       $user = $this->drupalCreateUser();
       $this->drupalLogin($user);
       $headers = $this->drupalGetHeaders(TRUE);
@@ -91,6 +87,15 @@ function testInternalBrowser() {
       ));
       $headers = $this->drupalGetHeaders(TRUE);
       $this->assertEqual(count($headers), 2, 'Simpletest stopped following redirects after the first one.');
+
+      // Remove the Simpletest settings.php so we can test the protection
+      // against requests that forge a valid testing user agent to gain access
+      // to the installer.
+      drupal_unlink($this->public_files_directory . '/settings.php');
+      global $base_url;
+      $this->drupalGet(url($base_url . '/core/install.php', array('external' => TRUE, 'absolute' => TRUE)));
+      $this->assertResponse(403, 'Cannot access install.php.');
+
     }
   }
 
diff --git a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
index f1f5336..0b26ca9 100644
--- a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
+++ b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
@@ -778,6 +778,22 @@ protected function setUp() {
     $this->settingsSet('cache', array('default' => 'cache.backend.memory'));
     $parameters = $this->installParameters();
     install_drupal($parameters);
+
+    // Set the install_profile so that web requests to the requests to the child
+    // site have the correct profile.
+    $settings = array(
+      'settings' => array(
+        'install_profile' => (object) array(
+          'value'    => $this->profile,
+          'required' => TRUE,
+        ),
+      ),
+    );
+    $this->writeSettings($settings);
+    // Override install profile in Settings to so the correct profile is used by
+    // tests.
+    $this->settingsSet('install_profile', $this->profile);
+
     $this->settingsSet('cache', array());
     $this->rebuildContainer();
 
diff --git a/core/modules/system/lib/Drupal/system/Tests/Bootstrap/GetFilenameUnitTest.php b/core/modules/system/lib/Drupal/system/Tests/Bootstrap/GetFilenameUnitTest.php
index d2d4cc7..c939630 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Bootstrap/GetFilenameUnitTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Bootstrap/GetFilenameUnitTest.php
@@ -26,6 +26,11 @@ public static function getInfo() {
    * Tests that drupal_get_filename() works when the file is not in database.
    */
   function testDrupalGetFilename() {
+    // drupal_get_profile() is using obtaining the profile from state if the
+    // install_state global is not set.
+    global $install_state;
+    $install_state['parameters']['profile'] = 'testing';
+
     // Assert that the test is meaningful by making sure the keyvalue service
     // does not exist.
     $this->assertFalse(drupal_container()->has('keyvalue'), 'The container has no keyvalue service.');
diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/BareMinimalAnonymousUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/BareMinimalAnonymousUpgradePathTest.php
index 01ce148..936dc9e 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/BareMinimalAnonymousUpgradePathTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/BareMinimalAnonymousUpgradePathTest.php
@@ -28,9 +28,15 @@ public function setUp() {
 
     // Override $update_free_access in settings.php to allow the anonymous user
     // to run updates.
-    $settings['settings']['update_free_access'] = (object) array(
-      'value' => TRUE,
-      'required' => TRUE,
+    $settings['settings'] = array(
+      'update_free_access' => (object) array(
+        'value' => TRUE,
+        'required' => TRUE,
+      ),
+      'install_profile' => (object) array(
+        'value'    => $this->profile,
+        'required' => TRUE,
+      ),
     );
     $this->writeSettings($settings);
   }
diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/UpgradePathTestBase.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/UpgradePathTestBase.php
index d7052fa..d983c68 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/UpgradePathTestBase.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/UpgradePathTestBase.php
@@ -146,6 +146,21 @@ protected function setUp() {
 
     $this->pass('Finished loading the dump.');
 
+    // Override $update_free_access in settings.php to allow the anonymous user
+    // to run updates.
+    $install_profile = unserialize(db_query('SELECT value FROM {variable} WHERE name = :name', array(':name' => 'install_profile'))->fetchField());
+    $settings = array(
+      'settings' => array(
+        'install_profile' => (object) array(
+          'value'    => $install_profile,
+          'required' => TRUE,
+        ),
+      ),
+    );
+    $this->writeSettings($settings);
+    $this->settingsSet('install_profile', $install_profile);
+    $this->profile = $install_profile;
+
     // Ensure that the session is not written to the new environment and replace
     // the global $user session with uid 1 from the new test site.
     drupal_save_session(FALSE);
diff --git a/core/modules/system/tests/upgrade/drupal-7.system.database.php b/core/modules/system/tests/upgrade/drupal-7.system.database.php
index beebe4e..f15d406 100644
--- a/core/modules/system/tests/upgrade/drupal-7.system.database.php
+++ b/core/modules/system/tests/upgrade/drupal-7.system.database.php
@@ -243,3 +243,8 @@
     'value' => serialize('public://color/seven-09696463/dummy-screenshot.png'),
   ))
   ->execute();
+
+db_update('variable')
+  ->fields(array('value' => 's:7:"minimal";'))
+  ->condition('name', 'install_profile')
+  ->execute();
