-
Notifications
You must be signed in to change notification settings - Fork 494
Guard git command arguments against flag injection (Sighthound findings) #52401
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,6 +19,13 @@ import ( | |
|
|
||
| var gitLog = logger.New("cli:git") | ||
|
|
||
| // isSafeGitRevisionArg reports whether ref cannot be misinterpreted as a git | ||
| // CLI flag by rejecting empty strings and values starting with "-". It does | ||
| // not validate that ref is a well-formed git revision. | ||
| func isSafeGitRevisionArg(ref string) bool { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [/diagnosing-bugs] The function name and comment say "safe git revision arg" but the implementation only blocks leading-dash flag injection — it does not validate rev syntax. This over-broad name may invite callers to rely on a guarantee it doesn't provide. 💡 SuggestionNarrow the doc comment to the actual invariant: // isSafeGitRevisionArg reports whether ref cannot be misinterpreted as a
// git CLI flag (non-empty, no leading dash). It does NOT validate that
// ref is a well-formed git revision.This prevents future callers from treating it as a full validation gate. @copilot please address this.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated the helper comment in 8562188 to state the exact invariant: it rejects empty and dash-prefixed values to prevent flag interpretation, but does not validate Git revision syntax. |
||
| return ref != "" && !strings.HasPrefix(ref, "-") | ||
| } | ||
|
|
||
| func isGitRepo() bool { | ||
| _, err := gitutil.FindGitRoot() | ||
| return err == nil | ||
|
|
@@ -689,6 +696,11 @@ func checkWorkflowFileStatus(workflowPath string) (*WorkflowFileStatus, error) { | |
| upstream := strings.TrimSpace(string(output)) | ||
| gitLog.Printf("Upstream branch: %s", upstream) | ||
|
|
||
| if !isSafeGitRevisionArg(upstream) { | ||
| gitLog.Printf("Rejecting unsafe upstream ref: %q", upstream) | ||
| return status, fmt.Errorf("unexpected upstream ref %q", upstream) | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [/diagnosing-bugs] On an unsafe upstream ref the function silently returns the current status with no error. Callers that rely on the returned status to decide whether to alert the user will silently skip the diff check — potentially hiding real workflow drift. 💡 SuggestionReturn a wrapped error so the caller can decide how to surface it: if !isSafeGitRevisionArg(upstream) {
return status, fmt.Errorf("unexpected upstream ref %q", upstream)
}The caller can then log a warning and fall through gracefully, rather than silently losing the check. @copilot please address this.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated |
||
|
|
||
| // Check if there are commits in the current branch that affect this file and aren't in upstream | ||
| cmd = exec.Command("git", "-C", gitRoot, "log", upstream+"..HEAD", "--oneline", "--", relPath) | ||
| output, err = cmd.Output() | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[/tdd]
loadLocalMetricEvalResultsreturnsnilon an unsafe ref, but no test covers this path. A regression could re-open the injection vector silently.💡 Suggested test skeleton
Combine with a spy/mock on
exec.Commandto assert the command is never invoked.@copilot please address this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No caller-path test added:
workflowIDis always prefixed byWorkflowStateBranchNameand thenorigin/, soloadLocalMetricEvalResults("--evil")cannot produce a dash-leading Git argument or exercise this guard. The security invariant itself remains directly covered byTestIsSafeGitRevisionArg.