@@ -75,8 +75,13 @@ func FormatContext(contexts []FileContext) string {
7575
7676// DiffBase returns the diff of the current branch against a base branch.
7777func DiffBase (base string ) (string , error ) {
78+ if err := validateGitRef (base ); err != nil {
79+ return "" , err
80+ }
81+ // #nosec G204 — base validated by validateGitRef
7882 out , err := exec .Command ("git" , "diff" , base + "...HEAD" ).Output ()
7983 if err != nil {
84+ // #nosec G204 — base validated by validateGitRef
8085 out2 , err2 := exec .Command ("git" , "diff" , base ).Output ()
8186 if err2 != nil {
8287 return "" , fmt .Errorf ("git diff failed: %w" , err )
@@ -88,6 +93,10 @@ func DiffBase(base string) (string, error) {
8893
8994// ChangedFiles returns the list of files changed relative to a base.
9095func ChangedFiles (base string ) ([]string , error ) {
96+ if err := validateGitRef (base ); err != nil {
97+ return nil , err
98+ }
99+ // #nosec G204 — base validated by validateGitRef
91100 out , err := exec .Command ("git" , "diff" , "--name-only" , base + "...HEAD" ).Output ()
92101 if err != nil {
93102 return nil , fmt .Errorf ("git diff --name-only failed: %w" , err )
@@ -111,6 +120,7 @@ func Blame(file string, startLine, endLine int) (string, error) {
111120 "--" , file ,
112121 }
113122
123+ // #nosec G204 — file validated by validateFilePath above, startLine/endLine are ints
114124 out , err := exec .Command ("git" , args ... ).Output ()
115125 if err != nil {
116126 return "" , fmt .Errorf ("git blame failed: %w" , err )
@@ -119,6 +129,20 @@ func Blame(file string, startLine, endLine int) (string, error) {
119129 return parseBlameAuthors (string (out )), nil
120130}
121131
132+ // validateGitRef ensures a git ref (branch, tag, SHA) contains no dangerous characters.
133+ func validateGitRef (ref string ) error {
134+ if ref == "" {
135+ return fmt .Errorf ("empty git ref" )
136+ }
137+ if ref [0 ] == '-' {
138+ return fmt .Errorf ("git ref %q starts with dash" , ref )
139+ }
140+ if strings .ContainsAny (ref , ";&|$`(){}[]<>!#*?\n \r \x00 \\ " ) {
141+ return fmt .Errorf ("git ref %q contains forbidden characters" , ref )
142+ }
143+ return nil
144+ }
145+
122146// validateFilePath ensures a file path does not traverse outside the working directory.
123147func validateFilePath (file string ) error {
124148 if file == "" {
@@ -146,6 +170,7 @@ func recentCommits(file string, n int) ([]string, error) {
146170 if err := validateFilePath (file ); err != nil {
147171 return nil , fmt .Errorf ("recentCommits: invalid path: %w" , err )
148172 }
173+ // #nosec G204 — file validated by validateFilePath above
149174 out , err := exec .Command ("git" , "log" , "--oneline" , "-n" , strconv .Itoa (n ), "--" , file ).Output ()
150175 if err != nil {
151176 return nil , err
0 commit comments