The vulnerability, CVE-2026-72869, describes an authenticated OS command injection in Dokploy's backup.restoreBackupWithLogs tRPC subscription. The root cause is the direct interpolation of user-controlled input (specifically databaseName, which maps to database, databaseUser, and databasePassword in the code) into shell commands executed via Node.js exec. This allows an authenticated user with backup:restore permission to inject arbitrary commands into the docker exec call, leading to host RCE.
The provided commit ccd2e83c57d99f725220d37e0152270e0827d71b clearly shows the fix for this issue across multiple database backup and restore functions. Before the fix, these functions constructed shell commands by directly embedding user-supplied values. For example, in getPostgresRestoreCommand, the databaseUser and database variables were directly placed within single quotes in the command string. This allowed an attacker to break out of the quotes and inject malicious commands.
The patch addresses this by:
- Importing the
quote function from shell-quote.
- Passing user-controlled values as environment variables to the
docker exec command using -e VAR=${quote([value])}.
- Referencing these values as
"$VAR" within a single-quoted inner script. This ensures that the user input is never directly part of the command text, preventing shell expansion and command injection.
Therefore, all functions that previously directly interpolated these user-controlled values into shell commands are considered vulnerable. These include getPostgresRestoreCommand, getMariadbRestoreCommand, getMysqlRestoreCommand, getMongoRestoreCommand from packages/server/src/utils/restore/utils.ts, and getPostgresBackupCommand, getMariadbBackupCommand, getMysqlBackupCommand, getMongoBackupCommand, getLibsqlBackupCommand from packages/server/src/utils/backups/utils.ts. An attacker would trigger these functions by initiating a backup or restore operation with specially crafted database parameters.