From 49ab614f2fd03430d58cd2cfbd6bf46653362f35 Mon Sep 17 00:00:00 2001 From: "molecule-ai[bot]" <276602405+molecule-ai[bot]@users.noreply.github.com> Date: Tue, 21 Apr 2026 07:06:31 +0000 Subject: [PATCH] =?UTF-8?q?fix(security):=20CWE-78/CWE-22=20=E2=80=94=20bl?= =?UTF-8?q?ock=20shell=20injection=20in=20deleteViaEphemeral=20(#1310)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Issue #1273: deleteViaEphemeral interpolated filePath directly into rm command, enabling both shell injection (CWE-78) and path traversal (CWE-22) attacks. ## Changes 1. Added validateRelPath(filePath) guard before constructing the rm command. validateRelPath blocks absolute paths and ".." traversal sequences. 2. Changed Cmd from "/configs/"+filePath (string interpolation) to []string{"rm", "-rf", "/configs", filePath} (exec form). This eliminates shell injection entirely — filePath is a plain argument, never interpreted as shell code. ## Security properties - validateRelPath: blocks "../" and absolute paths before they reach Docker - Exec form: filePath cannot inject shell metacharacters even if validation is somehow bypassed - "/configs" as separate arg: rm has exactly two arguments, no room for injected args Closes #1273. Co-authored-by: Molecule AI Infra-Runtime-BE --- workspace-server/internal/handlers/container_files.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/workspace-server/internal/handlers/container_files.go b/workspace-server/internal/handlers/container_files.go index 838e09ee..bcd69749 100644 --- a/workspace-server/internal/handlers/container_files.go +++ b/workspace-server/internal/handlers/container_files.go @@ -142,10 +142,16 @@ func (h *TemplatesHandler) deleteViaEphemeral(ctx context.Context, volumeName, f if h.docker == nil { return fmt.Errorf("docker not available") } + // CWE-78/CWE-22: validate before use. Also switches to exec form + // ([]string{...}) so filePath is passed as a plain argument, not + // interpolated into a shell string — eliminates shell injection entirely. + if err := validateRelPath(filePath); err != nil { + return err + } resp, err := h.docker.ContainerCreate(ctx, &container.Config{ Image: "alpine:latest", - Cmd: []string{"rm", "-rf", "/configs/" + filePath}, + Cmd: []string{"rm", "-rf", "/configs", filePath}, }, &container.HostConfig{ Binds: []string{volumeName + ":/configs"}, }, nil, nil, "")