From ccd2e83c57d99f725220d37e0152270e0827d71b Mon Sep 17 00:00:00 2001 From: Mauricio Siu Date: Sun, 19 Jul 2026 22:54:44 -0600 Subject: [PATCH] fix(security): pass db backup/restore identifiers via env vars to avoid injection The backup and restore command builders interpolated database name / user / password directly into a 'docker exec ... {bash,sh} -c "..."' string executed via execAsync / execAsyncRemote. Because the values sit inside the outer shell's double quotes, a simple quote() is insufficient: the outer shell expands $(), backticks and $VAR before the inner quoting applies (double-nested shell). Values are now passed to the container as environment variables (docker exec -e VAR=) and referenced as "$VAR" inside a single-quoted inner script, so they never enter the inner command text and cannot break out of either shell layer. The rest of each command (pg_dump/mysqldump/etc., flags, | gzip) is unchanged. Closes GHSA-qc73-mp78-4833, GHSA-qf8x-98cv-92qh, GHSA-ww4j-wjrr-rq8v, GHSA-7m3w-rm5f-h4fr, GHSA-f7mp-9jfp-mjrr --- .../db-backup-restore-injection.test.ts | 106 ++++++++++++++++++ packages/server/src/utils/backups/utils.ts | 16 ++- packages/server/src/utils/restore/utils.ts | 12 +- 3 files changed, 125 insertions(+), 9 deletions(-) create mode 100644 apps/dokploy/__test__/backups/db-backup-restore-injection.test.ts diff --git a/apps/dokploy/__test__/backups/db-backup-restore-injection.test.ts b/apps/dokploy/__test__/backups/db-backup-restore-injection.test.ts new file mode 100644 index 000000000..d48644c95 --- /dev/null +++ b/apps/dokploy/__test__/backups/db-backup-restore-injection.test.ts @@ -0,0 +1,106 @@ +import { execSync } from "node:child_process"; +import { chmodSync, existsSync, rmSync, writeFileSync } from "node:fs"; +import { + getLibsqlBackupCommand, + getMariadbBackupCommand, + getMongoBackupCommand, + getMysqlBackupCommand, + getPostgresBackupCommand, +} from "@dokploy/server/utils/backups/utils"; +import { + getMariadbRestoreCommand, + getMongoRestoreCommand, + getMysqlRestoreCommand, + getPostgresRestoreCommand, +} from "@dokploy/server/utils/restore/utils"; +import { afterAll, beforeAll, describe, expect, it } from "vitest"; + +// A stub replacing the real `docker` binary. It ignores exec/-i/$CONTAINER_ID, +// exports the -e VAR=val pairs, and runs the inner `sh -c