Issue #1232572 by deviantintegral, joachim, cweagans, kenorb, bleen, webflo, ceng, Elijah Lynn, sriharsha.uppuluri: Add a variable to disable fixing file permissions in drupal_install_fix_file()
parent
18d44b50ff
commit
854898258d
|
@ -0,0 +1,115 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\system\Tests\System\SitesDirectoryHardeningTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\system\Tests\System;
|
||||
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\Core\Site\Settings;
|
||||
use Drupal\Core\StringTranslation\StringTranslationTrait;
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
|
||||
/**
|
||||
* Tests Drupal permissions hardening of /sites subdirectories.
|
||||
*
|
||||
* @group system
|
||||
*/
|
||||
class SitesDirectoryHardeningTest extends WebTestBase {
|
||||
use StringTranslationTrait;
|
||||
|
||||
/**
|
||||
* Tests the default behavior to restrict directory permissions is enforced.
|
||||
*
|
||||
* Checks both the the current sites directory and settings.php.
|
||||
*/
|
||||
public function testSitesDirectoryHardening() {
|
||||
$site_path = $this->kernel->getSitePath();
|
||||
$settings_file = $this->settingsFile($site_path);
|
||||
|
||||
// First, we check based on what the initial install has set.
|
||||
$this->assertTrue(drupal_verify_install_file($site_path, FILE_NOT_WRITABLE, 'dir'), new FormattableMarkup('Verified permissions for @file.', array('@file' => $site_path)));
|
||||
|
||||
// We intentionally don't check for settings.local.php as that file is
|
||||
// not created by Drupal.
|
||||
$this->assertTrue(drupal_verify_install_file($settings_file, FILE_EXIST|FILE_READABLE|FILE_NOT_WRITABLE), new FormattableMarkup('Verified permissions for @file.', array('@file' => $settings_file)));
|
||||
|
||||
$this->makeWritable($site_path);
|
||||
$this->checkSystemRequirements();
|
||||
|
||||
$this->assertTrue(drupal_verify_install_file($site_path, FILE_NOT_WRITABLE, 'dir'), new FormattableMarkup('Verified permissions for @file after manual permissions change.', array('@file' => $site_path)));
|
||||
$this->assertTrue(drupal_verify_install_file($settings_file, FILE_EXIST|FILE_READABLE|FILE_NOT_WRITABLE), new FormattableMarkup('Verified permissions for @file after manual permissions change.', array('@file' => $settings_file)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests writable files remain writable when directory hardening is disabled.
|
||||
*/
|
||||
public function testSitesDirectoryHardeningConfig() {
|
||||
$site_path = $this->kernel->getSitePath();
|
||||
$settings_file = $this->settingsFile($site_path);
|
||||
|
||||
// Disable permissions enforcement.
|
||||
$settings = Settings::getAll();
|
||||
$settings['skip_permissions_hardening'] = TRUE;
|
||||
new Settings($settings);
|
||||
$this->assertTrue(Settings::get('skip_permissions_hardening'), 'Able to set hardening to true');
|
||||
$this->makeWritable($site_path);
|
||||
|
||||
// Manually trigger the requirements check.
|
||||
$requirements = $this->checkSystemRequirements();
|
||||
$this->assertEqual(REQUIREMENT_WARNING, $requirements['configuration_files']['severity'], 'Warning severity is properly set.');
|
||||
$this->assertEqual($this->t('Protection disabled'), (string) $requirements['configuration_files']['description']['#context']['configuration_error_list']['#items'][0], 'Description is properly set.');
|
||||
|
||||
$this->assertTrue(is_writable($site_path), 'Site directory remains writable when automatically fixing permissions is disabled.');
|
||||
$this->assertTrue(is_writable($settings_file), 'settings.php remains writable when automatically fixing permissions is disabled.');
|
||||
|
||||
// Re-enable permissions enforcement.
|
||||
$settings = Settings::getAll();
|
||||
$settings['skip_permissions_hardening'] = FALSE;
|
||||
new Settings($settings);
|
||||
|
||||
// Manually trigger the requirements check.
|
||||
$this->checkSystemRequirements();
|
||||
|
||||
$this->assertFalse(is_writable($site_path), 'Site directory is protected when automatically fixing permissions is enabled.');
|
||||
$this->assertFalse(is_writable($settings_file), 'settings.php is protected when automatically fixing permissions is enabled.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks system runtime requirements.
|
||||
*
|
||||
* @return array
|
||||
* An array of system requirements.
|
||||
*/
|
||||
protected function checkSystemRequirements() {
|
||||
module_load_install('system');
|
||||
return system_requirements('runtime');
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the given path and settings file writable.
|
||||
*
|
||||
* @param string $site_path
|
||||
* The sites directory path, such as 'sites/default'.
|
||||
*/
|
||||
protected function makeWritable($site_path) {
|
||||
chmod($site_path, 0755);
|
||||
chmod($this->settingsFile($site_path), 0644);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path to settings.php
|
||||
*
|
||||
* @param string $site_path
|
||||
* The sites subdirectory path.
|
||||
*
|
||||
* @return string
|
||||
* The path to settings.php.
|
||||
*/
|
||||
protected function settingsFile($site_path) {
|
||||
$settings_file = $site_path . '/settings.php';
|
||||
return $settings_file;
|
||||
}
|
||||
}
|
|
@ -365,12 +365,25 @@ function system_requirements($phase) {
|
|||
else {
|
||||
$site_path = DrupalKernel::findSitePath(Request::createFromGlobals());
|
||||
}
|
||||
if (!drupal_verify_install_file($site_path, FILE_NOT_WRITABLE, 'dir')) {
|
||||
$conf_errors[] = t("The directory %file is not protected from modifications and poses a security risk. You must change the directory's permissions to be non-writable.", array('%file' => $site_path));
|
||||
// Allow system administrators to disable permissions hardening for the site
|
||||
// directory. This allows additional files in the site directory to be
|
||||
// updated when they are managed in a version control system.
|
||||
if (Settings::get('skip_permissions_hardening')) {
|
||||
$conf_errors[] = t('Protection disabled');
|
||||
// If permissions hardening is disabled, then only show a warning for a
|
||||
// writable file, as a reminder, rather than an error.
|
||||
$file_protection_severity = REQUIREMENT_WARNING;
|
||||
}
|
||||
else {
|
||||
// In normal operation, writable files or directories are an error.
|
||||
$file_protection_severity = REQUIREMENT_ERROR;
|
||||
if (!drupal_verify_install_file($site_path, FILE_NOT_WRITABLE, 'dir')) {
|
||||
$conf_errors[] = t("The directory %file is not protected from modifications and poses a security risk. You must change the directory's permissions to be non-writable.", array('%file' => $site_path));
|
||||
}
|
||||
}
|
||||
foreach (array('settings.php', 'settings.local.php', 'services.yml') as $conf_file) {
|
||||
$full_path = $site_path . '/' . $conf_file;
|
||||
if (file_exists($full_path) && !drupal_verify_install_file($full_path, FILE_EXIST|FILE_READABLE|FILE_NOT_WRITABLE)) {
|
||||
if (file_exists($full_path) && (Settings::get('skip_permissions_hardening') || !drupal_verify_install_file($full_path, FILE_EXIST|FILE_READABLE|FILE_NOT_WRITABLE))) {
|
||||
$conf_errors[] = t("The file %file is not protected from modifications and poses a security risk. You must change the file's permissions to be non-writable.", array('%file' => $full_path));
|
||||
}
|
||||
}
|
||||
|
@ -393,7 +406,7 @@ function system_requirements($phase) {
|
|||
}
|
||||
$requirements['configuration_files'] = array(
|
||||
'value' => t('Not protected'),
|
||||
'severity' => REQUIREMENT_ERROR,
|
||||
'severity' => $file_protection_severity,
|
||||
'description' => $description,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -93,3 +93,15 @@ $settings['extension_discovery_scan_tests'] = TRUE;
|
|||
* using these parameters in a request to rebuild.php.
|
||||
*/
|
||||
$settings['rebuild_access'] = TRUE;
|
||||
|
||||
/**
|
||||
* Skip file system permissions hardening.
|
||||
*
|
||||
* The system module will periodically check the permissions of your site's
|
||||
* site directory to ensure that it is not writable by the website user. For
|
||||
* sites that are managed with a version control system, this can cause problems
|
||||
* when files in that directory such as settings.php are updated, because the
|
||||
* user pulling in the changes won't have permissions to modify files in the
|
||||
* directory.
|
||||
*/
|
||||
$settings['skip_permissions_hardening'] = TRUE;
|
||||
|
|
Loading…
Reference in New Issue