Problem/Motivation
In some scenarios it is possible to access the /core/install.php even when a site is already installed. This can lead to regenerating the admin user. Original raised with the security team but advised its fine to publicly post.
This is possible because this code here in core/includes/install.core.inc
if ($install_state['config_verified'] && empty($task)) {
if (count($kernel->getConfigStorage()->listAll())) {
$task = NULL;
throw new AlreadyInstalledException($container->get('string_translation'));
}
}
Checks that $task is empty, and if not it assumes its in the new installation process and let's the install continue without throwing the AlreadyInstalledException.
When translations are pending import, the task is set as `install_import_translations` because this code will result in TRUE:
$needs_translations = $locale_module_installed && ((count($install_state['translations']) > 1 && !empty($install_state['parameters']['langcode']) && $install_state['parameters']['langcode'] != 'en') || \Drupal::languageManager()->isMultilingual());
Steps to reproduce
You can see this issue by:
- Create a drupal site
- Install the site and enable translations
- Deploy with any importing translation failure
- Go to /core/install.php and reinstall Drupal, setting the admin user and password to whatever you want
- Go to the site on completion and login as your new admin user. The existing database is not wiped, but the admin user is overridden
Note that the Contact module must also be enabled on the site otherwise the install process triggers a fatal error stopping the above from happening. So probably many sites don't have this potential issue as a result.
A simpler way to reproduce on any site programmatically without having to reproduce a more complex failure:
- Run
drush state:set install_task 'install_import_translations' --input-format=string
- Go to /core/install.php and reinstall Drupal, setting the admin user and password to whatever you want
- Go to the site on completion and login as your new admin user. The existing database is not wiped, but the admin user is overridden
Proposed resolution
Double-check that Drupal is not yet installed.
For those coming across this same issue, if you get any import translation failure, you can manually run the following to re-protect your site:drush state:set install_task 'done' --input-format=string
Remaining tasks
Provide an additional check
User interface changes
None
API changes
None
Data model changes
None
Release notes snippet
Prevent re-installation of Drupal