diff --git a/pkg/cli/upgrade_command_test.go b/pkg/cli/upgrade_command_test.go index 6a2aa3c6f2f..84412f8e11b 100644 --- a/pkg/cli/upgrade_command_test.go +++ b/pkg/cli/upgrade_command_test.go @@ -4,6 +4,7 @@ package cli import ( "context" + "io" "os" "testing" @@ -165,6 +166,34 @@ func TestRelaunchWithSameArgsAllowsEmptyForwardedArgument(t *testing.T) { require.NoError(t, err) } +func TestRelaunchWithSameArgsPassesShellMetacharactersLiterally(t *testing.T) { + origArgs := os.Args + origStdout := os.Stdout + t.Cleanup(func() { + os.Args = origArgs + os.Stdout = origStdout + }) + os.Args = []string{"gh-aw", "upgrade", ";", "$(whoami)"} + + readOutput, writeOutput, err := os.Pipe() + require.NoError(t, err) + writeOutputClosed := false + t.Cleanup(func() { + _ = readOutput.Close() + if !writeOutputClosed { + _ = writeOutput.Close() + } + }) + os.Stdout = writeOutput + + require.NoError(t, relaunchWithSameArgs("--skip-extension-upgrade", "/bin/echo")) + require.NoError(t, writeOutput.Close()) + writeOutputClosed = true + output, err := io.ReadAll(readOutput) + require.NoError(t, err) + require.Equal(t, "upgrade ; $(whoami) --skip-extension-upgrade\n", string(output)) +} + func TestRelaunchWithSameArgsRejectsUnknownExtraFlag(t *testing.T) { err := relaunchWithSameArgs("--unknown-flag", "/bin/echo") require.Error(t, err) diff --git a/pkg/workflow/argument_injection_test.go b/pkg/workflow/argument_injection_test.go index 3dfec340e2a..0f79b59e1a1 100644 --- a/pkg/workflow/argument_injection_test.go +++ b/pkg/workflow/argument_injection_test.go @@ -370,6 +370,26 @@ func TestValidatePipPackageName(t *testing.T) { expectError: true, errContains: "PyPI names must start and end with a letter or digit, with hyphens, underscores, or dots allowed inside (e.g. \"requests\" or \"my-package\")", }, + { + name: "shell separator is rejected", + pkg: "pkg;whoami", + expectError: true, + }, + { + name: "command substitution is rejected", + pkg: "pkg$(whoami)", + expectError: true, + }, + { + name: "newline option injection is rejected", + pkg: "pkg\n--index-url", + expectError: true, + }, + { + name: "empty name is rejected", + pkg: "", + expectError: true, + }, } for _, tt := range tests {