Skip to content

[BUG]: DB migrations fail when the database password contains shell/URL-special characters #2176

@linuxkd

Description

@linuxkd

Version Information

Backend: v1.0.0-rainbow / dev build (the migration-based "rainbow" line). Code at src/inc/startup/setup.php.

Hashcat

N/A (server startup / DB migration issue, not cracking).

Description

DB schema migrations run at container startup via the Rust sqlx CLI. The migration database connection URI (DSN) is built by naive string concatenation in src/inc/startup/setup.php and passed unquoted and non-URL-encoded to a shell exec():

$database_uri = StartupConfig::getInstance()->getDatabaseType() . "://" . StartupConfig::getInstance()->getDatabaseUser() . ":" . StartupConfig::getInstance()->getDatabasePassword() . "@" . StartupConfig::getInstance()->getDatabaseServer() . ":" . StartupConfig::getInstance()->getDatabasePort() . "/" . StartupConfig::getInstance()->getDatabaseDB();
exec('/usr/bin/sqlx migrate run --source ' . dirname(__FILE__) . '/../../migrations/' . StartupConfig::getInstance()->getDatabaseType() . '/ -D ' . $database_uri, $output, $retval);

If the database password (or username) contains characters that are special in a URL (@ : / # ? [ ]) or in a shell ($ & ; | < > ( ) *, space, backtick, etc.), the migration command breaks and the server fails to boot.

This affects both the mysql and postgres DSNs, since both are constructed the same way.

Symptoms

We hit this on a production deployment where the auto-generated DB master password contained $ and &. The container log showed:

Start initialization process...
sh: 1: @<db-host>:3306/<db>: not found
Failed to run migrations:
error: error with configuration: invalid port number
Hashtopolis setup.php failed (exit code 255)

The & in the password backgrounded the truncated shell command and split the DSN, so sqlx received a DSN with no host/port -> "invalid port number", and the shell tried to execute the @host:3306/db remainder as a command -> "not found".

Reproduce

Deploy with a DB password containing $ and & (very common with auto-generated passwords, e.g. an AWS RDS/Aurora random_password). Startup fails during the migration step.

Proposed fix

Two independent defects:

  1. URL-encode the userinfo components so URL-special characters survive: wrap the username and password in rawurlencode(...).
  2. Shell-quote the arguments passed to exec(): wrap the migrations source path and the $database_uri in escapeshellarg(...).

PR to follow.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions