fix(database): set PostgreSQL SSL certificate ownership (#11286)
This commit is contained in:
parent
b3789d4a36
commit
096a1f5f08
5 changed files with 38 additions and 12 deletions
|
|
@ -210,11 +210,11 @@ public function handle(StandaloneMariadb $database)
|
|||
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml pull";
|
||||
$this->commands[] = dockerStopCommand(10, $container_name, $this->database->destination->server).' 2>/dev/null || true';
|
||||
$this->commands[] = "docker rm -f $container_name 2>/dev/null || true";
|
||||
if ($this->database->enable_ssl) {
|
||||
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml run --rm --no-deps --user root --entrypoint chown $container_name mysql:mysql /etc/mysql/certs/server.key /etc/mysql/certs/server.crt";
|
||||
}
|
||||
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d";
|
||||
$this->commands[] = "echo 'Database started.'";
|
||||
if ($this->database->enable_ssl) {
|
||||
$this->commands[] = executeInDocker($this->database->uuid, 'chown mysql:mysql /etc/mysql/certs/server.crt /etc/mysql/certs/server.key');
|
||||
}
|
||||
|
||||
return remote_process($this->commands, $database->destination->server, callEventOnFinish: 'DatabaseStatusChanged');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -259,10 +259,10 @@ public function handle(StandaloneMongodb $database)
|
|||
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml pull";
|
||||
$this->commands[] = dockerStopCommand(10, $container_name, $this->database->destination->server).' 2>/dev/null || true';
|
||||
$this->commands[] = "docker rm -f $container_name 2>/dev/null || true";
|
||||
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d";
|
||||
if ($this->database->enable_ssl) {
|
||||
$this->commands[] = executeInDocker($this->database->uuid, 'chown mongodb:mongodb /etc/mongo/certs/server.pem');
|
||||
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml run --rm --no-deps --user root --entrypoint chown $container_name mongodb:mongodb /etc/mongo/certs/server.pem";
|
||||
}
|
||||
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d";
|
||||
$this->commands[] = "echo 'Database started.'";
|
||||
|
||||
return remote_process($this->commands, $database->destination->server, callEventOnFinish: 'DatabaseStatusChanged');
|
||||
|
|
|
|||
|
|
@ -211,12 +211,10 @@ public function handle(StandaloneMysql $database)
|
|||
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml pull";
|
||||
$this->commands[] = dockerStopCommand(10, $container_name, $this->database->destination->server).' 2>/dev/null || true';
|
||||
$this->commands[] = "docker rm -f $container_name 2>/dev/null || true";
|
||||
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d";
|
||||
|
||||
if ($this->database->enable_ssl) {
|
||||
$mysqlUser = escapeshellarg($this->database->mysql_user);
|
||||
$this->commands[] = executeInDocker($this->database->uuid, "chown {$mysqlUser}:{$mysqlUser} /etc/mysql/certs/server.crt /etc/mysql/certs/server.key");
|
||||
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml run --rm --no-deps --user root --entrypoint chown $container_name mysql:mysql /etc/mysql/certs/server.key /etc/mysql/certs/server.crt";
|
||||
}
|
||||
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d";
|
||||
|
||||
$this->commands[] = "echo 'Database started.'";
|
||||
|
||||
|
|
|
|||
|
|
@ -221,11 +221,10 @@ public function handle(StandalonePostgresql $database)
|
|||
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml pull";
|
||||
$this->commands[] = dockerStopCommand(10, $container_name, $this->database->destination->server).' 2>/dev/null || true';
|
||||
$this->commands[] = "docker rm -f $container_name 2>/dev/null || true";
|
||||
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d";
|
||||
if ($this->database->enable_ssl) {
|
||||
$postgresUser = escapeshellarg($this->database->postgres_user);
|
||||
$this->commands[] = executeInDocker($this->database->uuid, "chown {$postgresUser}:{$postgresUser} /var/lib/postgresql/certs/server.key /var/lib/postgresql/certs/server.crt");
|
||||
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml run --rm --no-deps --user root --entrypoint chown $container_name postgres:postgres /var/lib/postgresql/certs/server.key /var/lib/postgresql/certs/server.crt";
|
||||
}
|
||||
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d";
|
||||
$this->commands[] = "echo 'Database started.'";
|
||||
|
||||
return remote_process($this->commands, $database->destination->server, callEventOnFinish: 'DatabaseStatusChanged');
|
||||
|
|
|
|||
|
|
@ -21,6 +21,35 @@
|
|||
->toContain('chown');
|
||||
});
|
||||
|
||||
it('sets postgres SSL file ownership before starting the database container', function () {
|
||||
$source = file_get_contents(__DIR__.'/../../app/Actions/Database/StartPostgresql.php');
|
||||
|
||||
$permissionCommandPosition = strpos($source, '--entrypoint chown');
|
||||
$startCommandPosition = strpos($source, 'docker-compose.yml up -d');
|
||||
|
||||
expect($permissionCommandPosition)->not->toBeFalse()
|
||||
->and($startCommandPosition)->not->toBeFalse()
|
||||
->and($permissionCommandPosition)->toBeLessThan($startCommandPosition)
|
||||
->and($source)->toContain('postgres:postgres /var/lib/postgresql/certs/server.key')
|
||||
->not->toContain('chown {$postgresUser}:{$postgresUser}');
|
||||
});
|
||||
|
||||
it('sets database SSL file ownership before startup', function (string $action, string $owner, string $keyPath) {
|
||||
$source = file_get_contents(__DIR__."/../../app/Actions/Database/{$action}.php");
|
||||
|
||||
$permissionCommandPosition = strpos($source, '--entrypoint chown');
|
||||
$startCommandPosition = strpos($source, 'docker-compose.yml up -d');
|
||||
|
||||
expect($permissionCommandPosition)->not->toBeFalse()
|
||||
->and($startCommandPosition)->not->toBeFalse()
|
||||
->and($permissionCommandPosition)->toBeLessThan($startCommandPosition)
|
||||
->and($source)->toContain("{$owner} {$keyPath}");
|
||||
})->with([
|
||||
'mysql' => ['StartMysql', 'mysql:mysql', '/etc/mysql/certs/server.key'],
|
||||
'mariadb' => ['StartMariadb', 'mysql:mysql', '/etc/mysql/certs/server.key'],
|
||||
'mongodb' => ['StartMongodb', 'mongodb:mongodb', '/etc/mongo/certs/server.pem'],
|
||||
]);
|
||||
|
||||
it('advisory PoC postgres_user payload is contained by escapeshellarg in chown command', function () {
|
||||
// Simulates a legacy row that bypassed validation
|
||||
$maliciousUser = 'root; touch /tmp/pwned_rce; #';
|
||||
|
|
|
|||
Loading…
Reference in a new issue