From bf2706a87c6cdb4cff9189c080b9cca9cb1812af Mon Sep 17 00:00:00 2001 From: Josh Date: Thu, 19 Mar 2026 20:44:14 -0400 Subject: [PATCH 1/3] refactor(setup): Add shared generateDbPassword() to AbstractDatabase Signed-off-by: Josh --- lib/private/Setup/AbstractDatabase.php | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/lib/private/Setup/AbstractDatabase.php b/lib/private/Setup/AbstractDatabase.php index d07d4af91a6c0..a2369085e6f60 100644 --- a/lib/private/Setup/AbstractDatabase.php +++ b/lib/private/Setup/AbstractDatabase.php @@ -75,6 +75,27 @@ public function initialize(array $config): void { $this->tablePrefix = $dbTablePrefix; } + /** + * Generate a strong random password suitable for database user accounts. + * + * Guarantees at least 2 uppercase, 2 lowercase, 2 digit, and 2 symbol + * characters are present, with symbols filtered to exclude characters + * that are problematic in SQL string contexts (", \, ', `). + * + * @return string A 30-character random password + */ + protected function generateDbPassword(): string { + $safeSymbols = str_replace(['\"', '\\', '\'', '`'], '', ISecureRandom::CHAR_SYMBOLS); + + $password = $this->random->generate(22, ISecureRandom::CHAR_ALPHANUMERIC . $safeSymbols) + . $this->random->generate(2, ISecureRandom::CHAR_UPPER) + . $this->random->generate(2, ISecureRandom::CHAR_LOWER) + . $this->random->generate(2, ISecureRandom::CHAR_DIGITS) + . $this->random->generate(2, $safeSymbols); + + return str_shuffle($password); + } + /** * @param array $configOverwrite * @return \OC\DB\Connection From 08fc972477a897cfe1f036295caf9ce32de314a1 Mon Sep 17 00:00:00 2001 From: Josh Date: Thu, 19 Mar 2026 20:46:53 -0400 Subject: [PATCH 2/3] refactor(setup): Use shared generateDbPassword() in MySQL setup Signed-off-by: Josh --- lib/private/Setup/MySQL.php | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/lib/private/Setup/MySQL.php b/lib/private/Setup/MySQL.php index 24093ae97a40c..9de18d75a5196 100644 --- a/lib/private/Setup/MySQL.php +++ b/lib/private/Setup/MySQL.php @@ -13,7 +13,6 @@ use OC\DB\ConnectionAdapter; use OC\DB\MySqlTools; use OCP\IDBConnection; -use OCP\Security\ISecureRandom; class MySQL extends AbstractDatabase { public string $dbprettyname = 'MySQL/MariaDB'; @@ -127,14 +126,8 @@ private function createSpecificUser(string $username, IDBConnection $connection) $rootUser = $this->dbUser; $rootPassword = $this->dbPassword; - //create a random password so we don't need to store the admin password in the config file - $saveSymbols = str_replace(['\"', '\\', '\'', '`'], '', ISecureRandom::CHAR_SYMBOLS); - $password = $this->random->generate(22, ISecureRandom::CHAR_ALPHANUMERIC . $saveSymbols) - . $this->random->generate(2, ISecureRandom::CHAR_UPPER) - . $this->random->generate(2, ISecureRandom::CHAR_LOWER) - . $this->random->generate(2, ISecureRandom::CHAR_DIGITS) - . $this->random->generate(2, $saveSymbols); - $this->dbPassword = str_shuffle($password); + // Create a random password so we don't need to store the admin password in the config file + $this->dbPassword = $this->generateDbPassword(); try { //user already specified in config From 70c0b60a5fc6c6be61aacb238659b519e13f1642 Mon Sep 17 00:00:00 2001 From: Josh Date: Thu, 19 Mar 2026 20:48:42 -0400 Subject: [PATCH 3/3] refactor(setup): Use shared generateDbPassword() in PostgreSQL setup Signed-off-by: Josh --- lib/private/Setup/PostgreSQL.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/private/Setup/PostgreSQL.php b/lib/private/Setup/PostgreSQL.php index 5ace7f6bcbee3..189a6a969a4aa 100644 --- a/lib/private/Setup/PostgreSQL.php +++ b/lib/private/Setup/PostgreSQL.php @@ -11,8 +11,6 @@ use OC\DatabaseSetupException; use OC\DB\Connection; use OC\DB\QueryBuilder\Literal; -use OCP\Security\ISecureRandom; -use OCP\Server; class PostgreSQL extends AbstractDatabase { public $dbprettyname = 'PostgreSQL'; @@ -48,8 +46,9 @@ public function setupDatabase(): void { //add prefix to the postgresql user name to prevent collisions $this->dbUser = 'oc_admin'; - //create a new password so we don't need to store the admin config in the config file - $this->dbPassword = Server::get(ISecureRandom::class)->generate(30, ISecureRandom::CHAR_ALPHANUMERIC); + + // Create a new password so we don't need to store the admin config in the config file + $this->dbPassword = $this->generateDbPassword(); $this->createDBUser($connection); }