From 4ca05414af2390f1be87154418d88aa5c828bd8f Mon Sep 17 00:00:00 2001 From: Leonhard Breuer Date: Wed, 3 Sep 2025 19:52:01 +0200 Subject: [PATCH] fix: use shellsafe docker command - add `shEscape` function - add `safeDockerLoginCommand` - use the new functions to contruct better registry login command --- packages/server/src/services/registry.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/server/src/services/registry.ts b/packages/server/src/services/registry.ts index 6468cd970..7c16bf017 100644 --- a/packages/server/src/services/registry.ts +++ b/packages/server/src/services/registry.ts @@ -10,6 +10,18 @@ import { IS_CLOUD } from "../constants"; export type Registry = typeof registry.$inferSelect; +function shQ(s: string): string { + if (!s) return "''"; + return `'${s.replace(/'/g, `'\\''`)}'`; +} + +function safeDockerLoginCommand(registry: string, user: string, pass: string) { + const escapedRegistry = shQ(registry) + const escapedUser = shQ(user) + const escapedPassword = shQ(pass) + return `echo ${escapedPassword} | docker login ${escapedRegistry} -u ${escapedUser} --password-stdin`; +} + export const createRegistry = async ( input: typeof apiCreateRegistry._type, organizationId: string, @@ -37,7 +49,7 @@ export const createRegistry = async ( message: "Select a server to add the registry", }); } - const loginCommand = `echo ${input.password} | docker login ${input.registryUrl} --username ${input.username} --password-stdin`; + const loginCommand = safeDockerLoginCommand(input.registryUrl, input.username, input.password) if (input.serverId && input.serverId !== "none") { await execAsyncRemote(input.serverId, loginCommand); } else if (newRegistry.registryType === "cloud") {