mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
Merge pull request #48 from silverstripe-security/pulls/4.0/fix-install-redacting
[SS-2017-010] Prevent install.php from disclosing system passwords
This commit is contained in:
commit
b46b858847
@ -26,18 +26,23 @@ class InstallConfig
|
||||
*
|
||||
* @param array $request Request object
|
||||
* @param array $databaseClasses Supported database config
|
||||
* @param bool $realPassword Set to true to get the real password. If false, any non-posted
|
||||
* password will be redacted as '********'. Note: Posted passwords are considered disclosed and
|
||||
* never redacted.
|
||||
* @return array
|
||||
*/
|
||||
public function getDatabaseConfig($request, $databaseClasses)
|
||||
public function getDatabaseConfig($request, $databaseClasses, $realPassword = true)
|
||||
{
|
||||
// Get config from request
|
||||
if (isset($request['db']['type'])) {
|
||||
$type = $request['db']['type'];
|
||||
if (isset($request['db'][$type])) {
|
||||
return array_merge(
|
||||
[ 'type' => $type ],
|
||||
$request['db'][$type]
|
||||
);
|
||||
$config = $request['db'][$type];
|
||||
// The posted placeholder must be substituted with the real password
|
||||
if (isset($config['password']) && $config['password'] === Installer::PASSWORD_PLACEHOLDER) {
|
||||
$config['password'] = Environment::getEnv('SS_DATABASE_PASSWORD') ?: '';
|
||||
}
|
||||
return array_merge([ 'type' => $type ], $config);
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,8 +51,16 @@ class InstallConfig
|
||||
'type' => $this->getDatabaseClass($databaseClasses),
|
||||
'server' => Environment::getEnv('SS_DATABASE_SERVER') ?: 'localhost',
|
||||
'username' => Environment::getEnv('SS_DATABASE_USERNAME') ?: 'root',
|
||||
'password' => Environment::getEnv('SS_DATABASE_PASSWORD') ?: '',
|
||||
'password' => $realPassword
|
||||
? (Environment::getEnv('SS_DATABASE_PASSWORD') ?: '')
|
||||
: Installer::PASSWORD_PLACEHOLDER, // Avoid password disclosure
|
||||
'database' => Environment::getEnv('SS_DATABASE_NAME') ?: 'SS_mysite',
|
||||
'path' => Environment::getEnv('SS_DATABASE_PATH')
|
||||
?: Environment::getEnv('SS_SQLITE_DATABASE_PATH') // sqlite compat
|
||||
?: null,
|
||||
'key' => Environment::getEnv('SS_DATABASE_KEY')
|
||||
?: Environment::getEnv('SS_SQLITE_DATABASE_KEY') // sqlite compat
|
||||
?: null,
|
||||
];
|
||||
}
|
||||
|
||||
@ -55,17 +68,26 @@ class InstallConfig
|
||||
* Get admin config from the environment
|
||||
*
|
||||
* @param array $request
|
||||
* @param bool $realPassword Set to true to get the real password. If false, any non-posted
|
||||
* password will be redacted as '********'. Note: Posted passwords are considered disclosed and
|
||||
* never redacted.
|
||||
* @return array
|
||||
*/
|
||||
public function getAdminConfig($request)
|
||||
public function getAdminConfig($request, $realPassword = true)
|
||||
{
|
||||
if (isset($request['admin'])) {
|
||||
$config = $request['admin'];
|
||||
if (isset($config['password']) && $config['password'] === Installer::PASSWORD_PLACEHOLDER) {
|
||||
$config['password'] = Environment::getEnv('SS_DEFAULT_ADMIN_PASSWORD') ?: '';
|
||||
}
|
||||
return $request['admin'];
|
||||
}
|
||||
|
||||
return [
|
||||
'username' => Environment::getEnv('SS_DEFAULT_ADMIN_USERNAME') ?: 'admin',
|
||||
'password' => Environment::getEnv('SS_DEFAULT_ADMIN_PASSWORD') ?: '',
|
||||
'password' => $realPassword
|
||||
? (Environment::getEnv('SS_DEFAULT_ADMIN_PASSWORD') ?: '')
|
||||
: Installer::PASSWORD_PLACEHOLDER, // Avoid password disclosure
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,11 @@ use SilverStripe\Security\Security;
|
||||
*/
|
||||
class Installer extends InstallRequirements
|
||||
{
|
||||
/**
|
||||
* value='' attribute placeholder for password fields
|
||||
*/
|
||||
const PASSWORD_PLACEHOLDER = '********';
|
||||
|
||||
protected function installHeader()
|
||||
{
|
||||
?>
|
||||
|
@ -123,14 +123,15 @@
|
||||
echo $checked ? '<div class="dbfields">' : '<div class="dbfields" style="display: none;">';
|
||||
if(isset($details['fields'])) foreach($details['fields'] as $fieldName => $fieldSpec) {
|
||||
$fieldTitle = $fieldSpec['title'];
|
||||
$fieldType = ($fieldName == 'password') ? 'password' : 'text';
|
||||
// values
|
||||
$defaultValue = (isset($fieldSpec['default'])) ? $fieldSpec['default'] : null;
|
||||
if($usingEnv && isset($fieldSpec['envVar']) && $envVar = getenv($fieldSpec['envVar'])) {
|
||||
$value = $envVar;
|
||||
} else {
|
||||
$value = (isset($databaseConfig[$fieldName]) && $databaseConfig['type'] == $class) ? $databaseConfig[$fieldName] : $defaultValue;
|
||||
}
|
||||
$fieldType = ($fieldName === 'password') ? 'password' : 'text';
|
||||
// Get display value
|
||||
if (isset($databaseConfig[$fieldName]) && $databaseConfig['type'] == $class) {
|
||||
$value = $databaseConfig[$fieldName];
|
||||
} elseif (isset($fieldSpec['default'])) {
|
||||
$value = $fieldSpec['default'];
|
||||
} else {
|
||||
$value = null;
|
||||
}
|
||||
|
||||
// attributes
|
||||
$attrs = array(
|
||||
|
@ -56,8 +56,8 @@ foreach ($databaseClasses as $class => $details) {
|
||||
|
||||
// Build config from config / environment / request
|
||||
$config = new InstallConfig();
|
||||
$databaseConfig = $config->getDatabaseConfig($_REQUEST, $databaseClasses);
|
||||
$adminConfig = $config->getAdminConfig($_REQUEST);
|
||||
$databaseConfig = $config->getDatabaseConfig($_REQUEST, $databaseClasses, true);
|
||||
$adminConfig = $config->getAdminConfig($_REQUEST, true);
|
||||
$alreadyInstalled = $config->alreadyInstalled();
|
||||
$silverstripe_version = $config->getFrameworkVersion();
|
||||
$sendStats = $config->canSendStats($_REQUEST);
|
||||
@ -107,22 +107,6 @@ if ($installFromCli && ($req->hasErrors() || $dbReq->hasErrors())) {
|
||||
// Path to client resources (copied through silverstripe/vendor-plugin)
|
||||
$clientPath = 'resources/silverstripe/framework/src/Dev/Install/client';
|
||||
|
||||
|
||||
// config-form.html vars (placeholder to prevent deletion)
|
||||
[
|
||||
$theme,
|
||||
$clientPath,
|
||||
$adminConfig,
|
||||
$usingEnv,
|
||||
$silverstripe_version,
|
||||
$locale,
|
||||
$locales,
|
||||
$webserverConfigFile,
|
||||
$hasErrorOtherThanDatabase,
|
||||
$hasOnlyWarnings, // If warnings but not errors
|
||||
$phpIniLocation
|
||||
];
|
||||
|
||||
// If already installed, ensure the user clicked "reinstall"
|
||||
$expectedArg = $alreadyInstalled ? 'reinstall' : 'go';
|
||||
if ((isset($_REQUEST[$expectedArg]) || $installFromCli)
|
||||
@ -142,7 +126,27 @@ if ((isset($_REQUEST[$expectedArg]) || $installFromCli)
|
||||
'admin' => $adminConfig,
|
||||
'stats' => $sendStats,
|
||||
]);
|
||||
// Show the config form
|
||||
} else {
|
||||
include(__DIR__ . '/config-form.html');
|
||||
return;
|
||||
}
|
||||
|
||||
// Sanitise config prior to rendering config-form.html
|
||||
$databaseConfig = $config->getDatabaseConfig($_REQUEST, $databaseClasses, false);
|
||||
$adminConfig = $config->getAdminConfig($_REQUEST, false);
|
||||
|
||||
// config-form.html vars (placeholder to prevent deletion)
|
||||
[
|
||||
$theme,
|
||||
$clientPath,
|
||||
$adminConfig,
|
||||
$databaseConfig,
|
||||
$usingEnv,
|
||||
$silverstripe_version,
|
||||
$locale,
|
||||
$locales,
|
||||
$webserverConfigFile,
|
||||
$hasErrorOtherThanDatabase,
|
||||
$hasOnlyWarnings, // If warnings but not errors
|
||||
$phpIniLocation,
|
||||
];
|
||||
|
||||
include(__DIR__ . '/config-form.html');
|
||||
|
Loading…
x
Reference in New Issue
Block a user