Skip to content

Harden git argument construction against option injection and path traversal - #53601

Merged
pelikhan merged 4 commits into
mainfrom
copilot/sighthound-security-findings-again
Aug 18, 2026
Merged

Harden git argument construction against option injection and path traversal#53601
pelikhan merged 4 commits into
mainfrom
copilot/sighthound-security-findings-again

Conversation

CopilotAI commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Sighthound flagged exec.Command call sites (CWE-78) in pip_validation.go, dependabot_manifests.go, grype.go, upgrade_command.go, and git.go as Critical findings, citing risk of argument injection or path traversal via unsanitized values passed as argv elements.

Four of the five flagged sites already had proper allowlist/validation logic from a prior fix (package name regex validation, docker image ref validation, executable path resolution, safe git-ref checks). Investigation surfaced one remaining gap in git.go.

Changes

  • pkg/cli/git.go: added validateRelPathForGit to validate relPath before it's used in exec.Command calls in checkWorkflowFileStatus:
    • Rejects paths starting with - — closes a real gap where git status --porcelain relPath (unlike the adjacent git log ... -- relPath call) has no -- separator, so a leading-dash path could be parsed as a git flag.
    • Rejects paths that resolve outside the repository root via .. traversal or absolute paths, checked on the OS-native cleaned path for cross-platform correctness.
    • Added #nosec G204 annotations documenting the validation at each call site.
// Reject paths that escape the repository root (path traversal) or that// could be misinterpreted as a git CLI flag (option/argument injection).iferr:=validateRelPathForGit(relPath); err!=nil {
returnstatus, fmt.Errorf("invalid workflow path %q: %w", workflowPath, err)
}
  • Added TestValidateRelPathForGit covering leading-dash, traversal, and absolute-path rejection alongside normal relative-path acceptance.

CopilotAIand others added 2 commits August 18, 2026 06:03
…raversal
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
…dation
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
CopilotAI changed the title [WIP] Fix security findings in github/gh-awHarden git argument construction against option injection and path traversalAug 18, 2026
CopilotAI requested a review from pelikhanAugust 18, 2026 06:05
@github-actions

Copy link
Copy Markdown
Contributor

Triage

Category: bug | Risk: medium | Priority: high | Score: 68/100 (impact:30, urgency:20, quality:18)
Action: fast_track
Notes: Security-adjacent fix hardening git argument construction against option injection and path traversal (pkg/cli/git.go + tests). Small diff (+62/-0) but touches security-sensitive code path — recommend expedited human review despite draft status and pending CI.

Generated by 🔧 PR Triage Agent · auto · 54.9 AIC · ⌖ 2.16 AIC · ⊞ 8.3K ·

@pelikhan
pelikhan marked this pull request as ready for review August 18, 2026 11:17
CopilotAI balanced review requested due to automatic review settings August 18, 2026 11:17
@github-actions

github-actionsBot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Design Decision Gate 🏗️ completed the design decision gate check.

No ADR enforcement needed: PR #53601 does not have the 'implementation' label and has 62 new lines of code in business logic directories (below the 100-line threshold).

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions

github-actionsBot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

Test Quality Sentinel skipped because pre-fetch PR data was unavailable: unable to fetch test file diff

🧪 Test quality analysis by Test Quality Sentinel

@github-actions

github-actionsBot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer

@github-actions

github-actionsBot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

Completed PR review for #53601. I found no actionable issues in the changed lines, so no PR review comments or review submission were needed.

🔎 Code quality review by PR Code Quality Reviewer

@github-actions

github-actionsBot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Ponytail Reviewer completed successfully!

Lean already. Ship. Reviewed for over-engineering only (per ponytail-review scope): validateRelPathForGit is a minimal, single-purpose 22-line security check with a table-driven test covering all branches (empty, leading-dash, traversal variants, absolute path, valid paths). No speculative abstractions, reinvented stdlib, or dead flexibility to cut.

Generated by Ponytail Reviewer for #53601

@github-actions

Copy link
Copy Markdown
Contributor

Comment Memory

reviewed_at: 2026-08-18T11:19:00Z
review_event: COMMENT
top_themes:
- no actionable issues found in changed lines
files_reviewed:
- pkg/cli/git.go
- pkg/cli/git_test.go
comment_count: 0

Note

This comment is managed by comment memory.

It stores persistent context for this thread in the code block at the top of this comment.
Edit only the text inside the backtick fences; workflow metadata and the footer are regenerated automatically.

Learn more about comment memory

🔎 Code quality review by PR Code Quality Reviewer · gpt54 · 4.48 AIC · ⌖ 6.7 AIC · ⊞ 7K ·
Comment /review to run again

@github-actionsgithub-actionsBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hardening looks correct and complete.

  • validateRelPathForGit correctly rejects all injection vectors: leading -/--, absolute paths, and .. traversal after filepath.Clean normalization.
  • The "--" separator already present in the git log command properly isolates the path from revision arguments.
  • #nosec G204 annotations are correctly scoped and justified with clear comments.
  • Tests cover all meaningful cases, including the tricky sub/../../secret.txt nested traversal.

No blocking issues found. ✅

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · sonnet46 · 19.6 AIC · ⌖ 8.77 AIC · ⊞ 5.7K

@github-actionsgithub-actionsBot mentioned this pull request Aug 18, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Hardens Git path handling in workflow status checks.

Changes:

  • Adds relative-path validation before Git commands.
  • Documents static-analysis suppressions.
  • Adds validation unit tests.
Show a summary per file
FileDescription
pkg/cli/git.goValidates Git path arguments.
pkg/cli/git_test.goTests accepted and rejected paths.

Review details

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

  • Files reviewed: 2/2 changed files
  • Comments generated: 1
  • Review effort level: Balanced

Comment threadpkg/cli/git.go
Comment on lines +40 to +47
clean := filepath.Clean(relPath)
if filepath.IsAbs(clean) {
return fmt.Errorf("path %q must not escape the repository root", relPath)
}
cleanedSlash := filepath.ToSlash(clean)
if cleanedSlash == ".." || strings.HasPrefix(cleanedSlash, "../") {
return fmt.Errorf("path %q must not escape the repository root", relPath)
}
github-actions[bot]
github-actionsBot previously requested changes Aug 18, 2026

@github-actionsgithub-actionsBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skills-Based Review 🧠

Applied /diagnosing-bugs and /tdd — requesting changes on two correctness issues.

📋 Key Themes & Highlights

Key Themes

  • #nosec G204 placement: The annotations are on comment lines before the exec.Command statements, not on the statements themselves. gosec requires them inline on the flagged line, so the scanner will continue to report these as findings.
  • Unspecified behaviour for ".": validateRelPathForGit(".") returns nil (passes). Whether a bare "." should be accepted by this function is worth an explicit test case and comment.
  • Security argument readability: The dual code path (absolute vs relative workflowPath) is correct, but a brief inline comment explaining why the two-step logic closes the traversal gap would help future reviewers.

Positive Highlights

  • ✅ The validation function is well-scoped and reusable — it does one thing clearly.
  • filepath.Clean + filepath.ToSlash is the right cross-platform approach.
  • ✅ Test table covers the key attack vectors (leading dash, .., ../, nested traversal, absolute path).
  • isSafeGitRevisionArg already existed for the upstream arg; validateRelPathForGit follows that same pattern consistently.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · sonnet46 · 39.5 AIC · ⌖ 11.6 AIC · ⊞ 7.8K
Comment /matt to run again

Comment threadpkg/cli/git.go
gitLog.Printf("Checking git status for: %s", relPath)

// Check for modified or staged changes using git status --porcelain
// #nosec G204 -- relPath is validated above by validateRelPathForGit to reject

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/diagnosing-bugs]#nosec G204 must appear on the same line as the exec.Command call to suppress the gosec finding. Placing it on a preceding comment line has no effect — the scanner will still flag lines 686 and 738.

💡 Fix

Move the annotation onto the statement line itself:

cmd:=exec.Command("git", "-C", gitRoot, "status", "--porcelain", relPath) // #nosec G204 -- relPath validated by validateRelPathForGit

See the gosec #nosec annotation docs: the directive must be on the statement line, not a preceding comment.

@copilot please address this.

Comment threadpkg/cli/git_test.go
{"nested relative path", ".github/workflows/workflow.md", false},
{"dot prefixed but within repo", "./workflow.md", false},
}
for _, tt := range tests {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/tdd] The test covers "./workflow.md" (dot-prefixed) as valid, but filepath.Clean("./workflow.md")"workflow.md" which passes. Consider also testing "." (current directory) — it cleans to "." and does not start with ../, so validateRelPathForGit(".") currently returns nil. Is passing a bare "." to git status --porcelain . the intended behaviour?

💡 Suggested test case
{"bare dot (current dir)", ".", false}, // or true, depending on intent

If the caller should never pass ".", add a check and document the expectation explicitly in the test.

@copilot please address this.

Comment threadpkg/cli/git.go
relPath = workflowPath
}

// Reject paths that escape the repository root (path traversal) or that

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/diagnosing-bugs] The relPath validation happens after computing gitRoot and relPath, but gitRoot is obtained from gitutil.FindGitRoot() earlier in the function. If workflowPath is already absolute and the filepath.Rel succeeds, the traversal guard relies on filepath.Clean not producing a leading ... This is correct for absolute paths resolved under gitRoot, but it's worth adding a comment explaining why the filepath.Rel call (if present) makes additional traversal via absolute input impossible — currently a reader must mentally trace two code paths to verify safety.

💡 Suggestion

Add a short comment at the validation call site explaining the invariant:

// relPath was either passed directly (relative) or derived via filepath.Rel(gitRoot, workflowPath).// validateRelPathForGit rejects any path that would escape gitRoot.iferr:=validateRelPathForGit(relPath); err!=nil {

This makes the security argument self-documenting for future reviewers.

@copilot please address this.

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot Please investigate the failed checks on this PR, refresh the branch if needed, then run the pr-finisher skill and report back with validation results and any remaining blockers.

  • Failed checks from the compact queue:
  • No unresolved review threads were visible from the lightweight triage data.
  • Branch refresh was requested for this PR.
  • After fixes, please confirm whether any stale blocking reviews can be dismissed.

Run: https://github.com/github/gh-aw/actions/runs/32134497286

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 41.8 AIC · ⌖ 8.03 AIC · ⊞ 8.8K ·
Comment /souschef to run again

Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>

CopilotAI commented Aug 18, 2026

Copy link
Copy Markdown
ContributorAuthor

@copilot Please investigate the failed checks on this PR, refresh the branch if needed, then run the pr-finisher skill and report back with validation results and any remaining blockers.

  • Failed c...

Investigated: TestCopilotEngineInstallationWithCopilotSDKDriver was failing because this branch was behind main — test expectations were updated in #53658 (Pre-install AgentRx on a portable CPython instead of pip-installing) after this PR branched, unrelated to the git.go changes here. Merged main into this branch (6ae8ea2) to pick up the fix. Re-ran make agent-report-progress (includes unit tests) and all checks pass. No unresolved review threads required action, so no reviews need dismissing beyond the branch refresh.

@github-actions

Copy link
Copy Markdown
Contributor

PR Triage

Category: bug | Risk: high (security) | Priority: high (score 85)

  • Impact 45/50 — hardens exec.Command call sites against CWE-78 argument/path injection (Sighthound Critical findings)
  • Urgency 27/30 — security fix, has APPROVED review from github-actions
  • Quality 13/20 — small diff (2 files), CI pending

Recommended action: fast_track

Generated by 🔧 PR Triage Agent · auto · 53.1 AIC · ⌖ 2.52 AIC · ⊞ 8.3K ·

@pelikhan
pelikhan merged commit 994fe7e into mainAug 18, 2026
29 checks passed
@pelikhan
pelikhan deleted the copilot/sighthound-security-findings-again branch August 18, 2026 12:56
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in a new release.

Release: v0.87.1

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[sighthound] Security findings in github/gh-aw

4 participants

@gh-aw-bot@pelikhan