fix(security): escape user input in git clone commands across all providers

User-controlled git fields (customGitUrl, branch names, repo owner/name,
gitlab namespace, SSH hostname) were interpolated unescaped into git clone /
ssh-keyscan shell commands run via execAsync / execAsyncRemote, allowing
authenticated OS command injection. All such values are now passed through
shell-quote before interpolation (defense at the sink, covering every code
path including the compose branch bypass).

Closes GHSA-qxcw-cx35-2hrw, GHSA-hrfh-82jj-3q46, GHSA-6693-xv3f-69px,
GHSA-qwwm-hc7m-7xp9, GHSA-grrj-6xrh-j6vp, GHSA-x2p2-qq8g-2mqq,
GHSA-cg8g-x23v-5fw8
This commit is contained in:
Mauricio Siu
2026-07-19 20:32:15 -06:00
parent 74811073f6
commit 47347ab885
6 changed files with 27 additions and 12 deletions

View File

@@ -9,6 +9,7 @@ import {
import type { InferResultType } from "@dokploy/server/types/with";
import { TRPCError } from "@trpc/server";
import type { z } from "zod";
import { shellWord } from "./utils";
export const refreshGitlabToken = async (gitlabProviderId: string) => {
const gitlabProvider = await findGitlabById(gitlabProviderId);
@@ -151,8 +152,8 @@ export const cloneGitlabRepository = async ({
command += `mkdir -p ${outputPath};`;
const repoClone = getGitlabRepoClone(gitlab, gitlabPathNamespace);
const cloneUrl = getGitlabCloneUrl(gitlab, repoClone);
command += `echo "Cloning Repo ${repoClone} to ${outputPath}: ✅";`;
command += `git clone --branch ${gitlabBranch} --depth 1 ${enableSubmodules ? "--recurse-submodules" : ""} ${cloneUrl} ${outputPath} --progress;`;
command += `echo ${shellWord(`Cloning Repo ${repoClone} to ${outputPath}: ✅`)};`;
command += `git clone --branch ${shellWord(gitlabBranch)} --depth 1 ${enableSubmodules ? "--recurse-submodules" : ""} ${shellWord(cloneUrl)} ${shellWord(outputPath)} --progress;`;
return command;
};