From ff73ec44966a63045aecdd04606cc1e6295cc6e5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 27 Aug 2026 12:06:18 +0000 Subject: [PATCH 1/4] Initial plan From eef71ab243e278ef74618736c32c228de63843fb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 27 Aug 2026 12:32:55 +0000 Subject: [PATCH 2/4] Harden docker scanner command argument validation Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/cli/grype.go | 10 ++++++++++ pkg/cli/zizmor.go | 15 +++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/pkg/cli/grype.go b/pkg/cli/grype.go index dd84d3108a3..25e813413d8 100644 --- a/pkg/cli/grype.go +++ b/pkg/cli/grype.go @@ -266,6 +266,9 @@ func grypeDockerArgs(validatedImageRef, configFile string) ([]string, error) { if err != nil { return nil, fmt.Errorf("invalid grype scanner image reference %q: %w", GrypeImage, err) } + if err := validateExecArgument(grypeImageRef); err != nil { + return nil, fmt.Errorf("invalid grype scanner image reference argument: %w", err) + } var configArgs []string if configFile != "" { @@ -273,6 +276,9 @@ func grypeDockerArgs(validatedImageRef, configFile string) ([]string, error) { if err != nil { return nil, fmt.Errorf("invalid grype container config path %q: %w", grypeContainerConfigPath, err) } + if err := validateExecArgument(containerConfigPath); err != nil { + return nil, fmt.Errorf("invalid grype container config path argument: %w", err) + } volumeMount, err := buildDockerReadonlyFileMount(configFile, containerConfigPath) if err != nil { return nil, fmt.Errorf("invalid grype config mount: %w", err) @@ -354,6 +360,10 @@ func grypeRunOnImage(imageRef, configFile string, verbose bool) (*grypeOutput, e if err != nil { return nil, fmt.Errorf("docker command not found: %w", err) } + dockerPath, err = fileutil.ValidateExecutablePath(dockerPath) + if err != nil { + return nil, fmt.Errorf("resolved docker executable path is invalid: %w", err) + } dockerArgs, err := grypeDockerArgs(validatedImageRef, configFile) if err != nil { diff --git a/pkg/cli/zizmor.go b/pkg/cli/zizmor.go index 546c752d897..0ed534f30fc 100644 --- a/pkg/cli/zizmor.go +++ b/pkg/cli/zizmor.go @@ -174,14 +174,29 @@ func buildZizmorCommand(lockFiles []string) (cmd *exec.Cmd, relPaths []string, d if err != nil { return nil, nil, nil, fmt.Errorf("docker command not found: %w", err) } + dockerPath, err = fileutil.ValidateExecutablePath(dockerPath) + if err != nil { + return nil, nil, nil, fmt.Errorf("resolved docker executable path is invalid: %w", err) + } volumeMount, err := buildDockerVolumeMount(gitRoot, "/workdir") if err != nil { return nil, nil, nil, fmt.Errorf("docker mount path for git root %q is invalid; expected an absolute host path. Example: /home/user/repo: %w", gitRoot, err) } + if err := validateExecArgument(volumeMount); err != nil { + return nil, nil, nil, fmt.Errorf("invalid docker volume mount argument %q: %w", volumeMount, err) + } zizmorImageRef, err := validateDockerImageRef(ZizmorImage) if err != nil { return nil, nil, nil, fmt.Errorf("zizmor scanner image reference %q is invalid; expected a registry reference. Example: ghcr.io/owner/image:tag: %w", ZizmorImage, err) } + if err := validateExecArgument(zizmorImageRef); err != nil { + return nil, nil, nil, fmt.Errorf("invalid zizmor scanner image argument %q: %w", zizmorImageRef, err) + } + for _, containerPath := range containerPaths { + if err := validateExecArgument(containerPath); err != nil { + return nil, nil, nil, fmt.Errorf("invalid zizmor scan path argument %q: %w", containerPath, err) + } + } dockerArgs = zizmorDockerArgs(zizmorImageRef, volumeMount, containerPaths) // #nosec G204 -- dockerPath is resolved from the allowlisted executable name "docker" via From fbf55146577102045ef5c6dff3c728d72f08701c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 27 Aug 2026 12:36:56 +0000 Subject: [PATCH 3/4] Polish grype validation error context Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/cli/grype.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/cli/grype.go b/pkg/cli/grype.go index 25e813413d8..85b3b17615b 100644 --- a/pkg/cli/grype.go +++ b/pkg/cli/grype.go @@ -267,7 +267,7 @@ func grypeDockerArgs(validatedImageRef, configFile string) ([]string, error) { return nil, fmt.Errorf("invalid grype scanner image reference %q: %w", GrypeImage, err) } if err := validateExecArgument(grypeImageRef); err != nil { - return nil, fmt.Errorf("invalid grype scanner image reference argument: %w", err) + return nil, fmt.Errorf("invalid grype scanner image reference argument %q: %w", grypeImageRef, err) } var configArgs []string @@ -277,7 +277,7 @@ func grypeDockerArgs(validatedImageRef, configFile string) ([]string, error) { return nil, fmt.Errorf("invalid grype container config path %q: %w", grypeContainerConfigPath, err) } if err := validateExecArgument(containerConfigPath); err != nil { - return nil, fmt.Errorf("invalid grype container config path argument: %w", err) + return nil, fmt.Errorf("invalid grype container config path argument %q: %w", containerConfigPath, err) } volumeMount, err := buildDockerReadonlyFileMount(configFile, containerConfigPath) if err != nil { From 640ba1312220c4f02d0fa0b06370947ac4f77f44 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 27 Aug 2026 15:12:03 +0000 Subject: [PATCH 4/4] Fix Docker scanner validation regressions Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/cli/grype.go | 10 ---------- pkg/cli/zizmor.go | 10 ---------- 2 files changed, 20 deletions(-) diff --git a/pkg/cli/grype.go b/pkg/cli/grype.go index 85b3b17615b..dd84d3108a3 100644 --- a/pkg/cli/grype.go +++ b/pkg/cli/grype.go @@ -266,9 +266,6 @@ func grypeDockerArgs(validatedImageRef, configFile string) ([]string, error) { if err != nil { return nil, fmt.Errorf("invalid grype scanner image reference %q: %w", GrypeImage, err) } - if err := validateExecArgument(grypeImageRef); err != nil { - return nil, fmt.Errorf("invalid grype scanner image reference argument %q: %w", grypeImageRef, err) - } var configArgs []string if configFile != "" { @@ -276,9 +273,6 @@ func grypeDockerArgs(validatedImageRef, configFile string) ([]string, error) { if err != nil { return nil, fmt.Errorf("invalid grype container config path %q: %w", grypeContainerConfigPath, err) } - if err := validateExecArgument(containerConfigPath); err != nil { - return nil, fmt.Errorf("invalid grype container config path argument %q: %w", containerConfigPath, err) - } volumeMount, err := buildDockerReadonlyFileMount(configFile, containerConfigPath) if err != nil { return nil, fmt.Errorf("invalid grype config mount: %w", err) @@ -360,10 +354,6 @@ func grypeRunOnImage(imageRef, configFile string, verbose bool) (*grypeOutput, e if err != nil { return nil, fmt.Errorf("docker command not found: %w", err) } - dockerPath, err = fileutil.ValidateExecutablePath(dockerPath) - if err != nil { - return nil, fmt.Errorf("resolved docker executable path is invalid: %w", err) - } dockerArgs, err := grypeDockerArgs(validatedImageRef, configFile) if err != nil { diff --git a/pkg/cli/zizmor.go b/pkg/cli/zizmor.go index 0ed534f30fc..c41b569e8e2 100644 --- a/pkg/cli/zizmor.go +++ b/pkg/cli/zizmor.go @@ -174,24 +174,14 @@ func buildZizmorCommand(lockFiles []string) (cmd *exec.Cmd, relPaths []string, d if err != nil { return nil, nil, nil, fmt.Errorf("docker command not found: %w", err) } - dockerPath, err = fileutil.ValidateExecutablePath(dockerPath) - if err != nil { - return nil, nil, nil, fmt.Errorf("resolved docker executable path is invalid: %w", err) - } volumeMount, err := buildDockerVolumeMount(gitRoot, "/workdir") if err != nil { return nil, nil, nil, fmt.Errorf("docker mount path for git root %q is invalid; expected an absolute host path. Example: /home/user/repo: %w", gitRoot, err) } - if err := validateExecArgument(volumeMount); err != nil { - return nil, nil, nil, fmt.Errorf("invalid docker volume mount argument %q: %w", volumeMount, err) - } zizmorImageRef, err := validateDockerImageRef(ZizmorImage) if err != nil { return nil, nil, nil, fmt.Errorf("zizmor scanner image reference %q is invalid; expected a registry reference. Example: ghcr.io/owner/image:tag: %w", ZizmorImage, err) } - if err := validateExecArgument(zizmorImageRef); err != nil { - return nil, nil, nil, fmt.Errorf("invalid zizmor scanner image argument %q: %w", zizmorImageRef, err) - } for _, containerPath := range containerPaths { if err := validateExecArgument(containerPath); err != nil { return nil, nil, nil, fmt.Errorf("invalid zizmor scan path argument %q: %w", containerPath, err)