Skip to content

Harden Git revision argument handling - #58412

Merged
pelikhan merged 6 commits into
mainfrom
copilot/sighthound-fix-security-findings
Sep 4, 2026
Merged

Harden Git revision argument handling#58412
pelikhan merged 6 commits into
mainfrom
copilot/sighthound-fix-security-findings

Conversation

Copilot AI commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

The security scan flagged dynamic process arguments as potential command injection. Existing call sites already avoid shell execution; this change further hardens Git revision handling.

  • Git invocation
    • Pass the upstream ref as a standalone git log --not argument instead of composing a revision expression.
    • Reject control characters in revision arguments.
exec.Command("git", "-C", gitRoot, "log",
    "--oneline", "HEAD", "--not", upstream, "--", relPath)
  • Regression coverage
    • Cover newline and Unicode control-character inputs.

Generated by 👨‍🍳 PR Sous Chef · pi · gpt54 · 31.4 AIC · ⌖ 8.64 AIC · ⊞ 8.9K ·
Comment /souschef to run again


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

Generated by 👨‍🍳 PR Sous Chef · pi · gpt54 · 20.6 AIC · ⌖ 8.82 AIC · ⊞ 9.2K ·
Comment /souschef to run again

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix critical command injection vulnerabilities Harden Git revision argument handling Sep 4, 2026
Copilot AI requested a review from pelikhan September 4, 2026 07:03
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Category: bug | Risk: medium | Score: 53 (impact 35 + urgency 10 + quality 8) | Action: batch_review | Batch: none

Generated by 🔧 PR Triage Agent · copilot · mai10 · 22.2 AIC · ⌖ 2.85 AIC · ⊞ 15.1K ·

1 similar comment
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Category: bug | Risk: medium | Score: 53 (impact 35 + urgency 10 + quality 8) | Action: batch_review | Batch: none

Generated by 🔧 PR Triage Agent · copilot · mai10 · 22.2 AIC · ⌖ 2.85 AIC · ⊞ 15.1K ·

@pelikhan
pelikhan marked this pull request as ready for review September 4, 2026 13:36
Copilot AI balanced review requested due to automatic review settings September 4, 2026 13:36

Copilot AI 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.

🟡 Changes recommended

The revised Git command path lacks regression coverage with a configured upstream.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Hardens Git revision handling against argument injection.

Changes:

  • Rejects control characters in revision arguments.
  • Passes upstream refs separately via git log --not.
  • Adds control-character validation tests.
File summaries
File Description
pkg/cli/git.go Hardens revision validation and Git invocation.
pkg/cli/git_test.go Covers unsafe control characters.
Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 1
  • Review effort level: Balanced

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

Comment thread pkg/cli/git.go
// #nosec G204 -- upstream is validated above by isSafeGitRevisionArg and relPath was
// validated by validateRelPathForGit; "--" separates revision args from the path.
cmd = exec.Command("git", "-C", gitRoot, "log", upstream+"..HEAD", "--oneline", "--", relPath)
cmd = exec.Command("git", "-C", gitRoot, "log", "--oneline", "HEAD", "--not", upstream, "--", relPath)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in 4bb01c8: I added the configured-upstream regression to TestCheckWorkflowFileStatus, asserting a workflow-specific local commit reports HasUnpushedCommits == true while an unrelated change remains false. I also split the long git helpers to satisfy the repo lint gate without changing behavior.

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

Completed PR review for #58412; submitted overall review with no additional line comments because the only actionable issue was already present in existing review comments.

🔎 Code quality review by PR Code Quality Reviewer

@github-actions

github-actions Bot commented Sep 4, 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-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Ponytail Reviewer failed. Please review the logs for details.

Warning

Threat Detection Engine Failure — The analysis engine could not complete. This is a tooling failure, not a security finding.

What happened

The threat detection engine failed to produce results.

Review the workflow run logs for details.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • ab.chatgpt.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "ab.chatgpt.com"

See Network Configuration for more information.

Generated by Ponytail Reviewer for #58412

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Design Decision Gate 🏗️ completed the design decision gate check. See the comment below for the result and any generated ADR draft.

No ADR enforcement needed: PR does not have the 'implementation' label and has ≤100 new lines of code in business logic directories.

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions

github-actions Bot commented Sep 4, 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

@gh-aw-bot

Copy link
Copy Markdown
Collaborator
pr-sous-chef

@copilot Please take the next forward-progress pass on this PR.

  • Current failed check: Unit tests (S-Z and other)
  • Review follow-up still needs code changes: pkg/cli/git.go review thread
  • Please add regression coverage for the configured-upstream path, address the failing unit test, refresh the branch if needed, and run the pr-finisher skill on current HEAD.
  • If anything remains after the code fix, summarize the maintainer-facing blocker clearly.

Generated by PR Sous Chef: https://github.com/github/gh-aw/actions/runs/33888975860

Generated by 👨‍🍳 PR Sous Chef · pi · gpt54 · 31.4 AIC · ⌖ 8.64 AIC · ⊞ 8.9K ·
Comment /souschef to run again

@github-actions github-actions Bot 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.

Reviewed via correctness/security fallback (backend Go change, no UI applicable). The revision-argument hardening is correct: swapping the composed upstream..HEAD string for the standalone --not upstream argument avoids injection via revision-expression concatenation, and isSafeGitRevisionArg now correctly rejects control characters (including newline and Unicode ``). New tests cover both cases. No blocking issues found.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · copilot · sonnet50 · 21.1 AIC · ⌖ 13.3 AIC · ⊞ 8.3K

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Comment Memory

reviewed_at: 2026-09-04T15:30:01.975+00:00
review_event: COMMENT
top_themes:
  - existing coverage gap for upstream-configured checkWorkflowFileStatus path was already noted
  - current diff is otherwise narrowly scoped and behavior-safe
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 · copilot · gpt54 · 17.9 AIC · ⌖ 7.32 AIC · ⊞ 23.5K ·
Comment /review to run again

@github-actions github-actions Bot 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.

Verdict

No new blocking issues in the current patch.

Why I'm not requesting changes

The only substantive risk I found is the existing test coverage gap already called out on this PR: the changed git log --not path still is not exercised by TestCheckWorkflowFileStatus, because those tests never configure an upstream branch. Beyond that, the revision hardening itself is appropriately narrow and the added control-character coverage is aligned with existing validation helpers.

🔎 Code quality review by PR Code Quality Reviewer · copilot · gpt54 · 17.9 AIC · ⌖ 7.32 AIC · ⊞ 23.5K
Comment /review to run again

@github-actions github-actions Bot 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 /tdd — the security hardening logic itself is sound, but the changed git log code path is still not exercised by a passing test.

📋 Key Themes & Highlights

Key Themes

  • Test coverage gap: checkWorkflowFileStatus's --not upstream invocation is never exercised because TestCheckWorkflowFileStatus never configures a real upstream branch (rev-parse @{u} fails first). A prior reviewer comment already flagged this; it remains open.
  • The new isSafeGitRevisionArg control-character tests (git_test.go) are correct and directly cover the new containsControlCharacters check with good edge cases (newline, U+202E RTL override).

Positive Highlights

  • ✅ Passing upstream as a standalone --not argument to git log instead of composing a revision expression (upstream+"..HEAD") is a real hardening improvement — it removes a string-concatenation surface that could be misinterpreted if upstream ever contained shell-adjacent characters.
  • ✅ Rejecting control characters (including Unicode format chars and line/paragraph separators) in isSafeGitRevisionArg closes a real gap: a ref containing \n or \r could previously be used to smuggle additional arguments/lines into git's argument parsing or terminal output.
  • ✅ Good, targeted new unit tests for the validation function itself.

Skill selection: change type is a bug-fix/security-hardening PR, so /tdd and /diagnosing-bugs were applied.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · copilot · sonnet50 · 21.8 AIC · ⌖ 14.7 AIC · ⊞ 10.3K
Comment /matt to run again

Comment thread pkg/cli/git.go
// #nosec G204 -- upstream is validated above by isSafeGitRevisionArg and relPath was
// validated by validateRelPathForGit; "--" separates revision args from the path.
cmd = exec.Command("git", "-C", gitRoot, "log", upstream+"..HEAD", "--oneline", "--", relPath)
cmd = exec.Command("git", "-C", gitRoot, "log", "--oneline", "HEAD", "--not", upstream, "--", relPath)

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 new git log --oneline HEAD --not upstream -- relPath invocation has no regression test exercising HasUnpushedCommits == true. TestCheckWorkflowFileStatus never configures an upstream/remote-tracking branch, so rev-parse @{u} always fails and this whole code path (including the argument-order change) is untested.

💡 Suggested test addition

Add a subtest that creates a fake remote-tracking ref (e.g. git update-ref refs/remotes/origin/main HEAD~1 plus git branch --set-upstream-to=origin/main), commits a new change on HEAD, and asserts status.HasUnpushedCommits == true. This would have caught any accidental swap between --not upstream and range syntax, and locks in the fix's actual behavior rather than just the string it produces.

t.Run("unpushed_commits", func(t *testing.T) {
    exec.Command("git", "update-ref", "refs/remotes/origin/main", "HEAD").Run()
    exec.Command("git", "branch", "--set-upstream-to=origin/main").Run()
    // ... commit a change to workflowFile on HEAD ...
    status, err := checkWorkflowFileStatus(workflowFile)
    require.NoError(t, err)
    assert.True(t, status.HasUnpushedCommits)
})

@copilot please address this.

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

Copy link
Copy Markdown
Collaborator

@copilot This PR looks ready for a forward-progress pass.

Warning

Firewall blocked 2 domains

The following domains were blocked by the firewall during workflow execution:

  • github.com
  • registry.npmjs.org

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "github.com"
    - "registry.npmjs.org"

See Network Configuration for more information.

Generated by 👨‍🍳 PR Sous Chef · pi · gpt54 · 20.8 AIC · ⌖ 8.72 AIC · ⊞ 9.2K ·
Comment /souschef to run again

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Category: bug | Risk: medium | Score: 60 (impact 28 urgency 18 quality 14) | Action: batch_review | Batch: workflow-reliability

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • api.github.com

[!TIP]
api.github.com is blocked because GitHub API access uses the built-in GitHub tools by default. Instead of adding api.github.com to network.allowed, use tools.github.mode: gh-proxy for direct pre-authenticated GitHub CLI access without requiring network access to api.github.com:

tools:
  github:
    mode: gh-proxy

See GitHub Tools for more information on gh-proxy mode.

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "api.github.com"

See Network Configuration for more information.

Generated by 🔧 PR Triage Agent · copilot · mai10 · 25.2 AIC · ⌖ 2.93 AIC · ⊞ 15.1K ·

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot The latest review thread already has an author follow-up but is still unresolved:

Please resolve the thread if the reviewer concern is fully addressed, then run the pr-finisher skill and push any remaining fixes if needed.

Generated by 👨‍🍳 PR Sous Chef · pi · gpt54 · 20.6 AIC · ⌖ 8.82 AIC · ⊞ 9.2K ·
Comment /souschef to run again

@gh-aw-bot

Copy link
Copy Markdown
Collaborator
pr-sous-chef

@copilot The latest review thread already has an author follow-up but is still unresolved.

  • Please resolve or directly address the remaining thread on the configured-upstream path coverage point.
  • If a code change is still needed, push it and rerun the pr-finisher skill.
  • If the thread is already satisfied on HEAD and only GitHub review state remains, say that explicitly in a maintainer-facing summary.

Thread to close out:

Generated by PR Sous Chef: https://github.com/github/gh-aw/actions/runs/33908460692

Generated by 👨‍🍳 PR Sous Chef · pi · gpt54 · 33.4 AIC · ⌖ 8.81 AIC · ⊞ 9.2K ·
Comment /souschef to run again

@pelikhan

pelikhan commented Sep 4, 2026

Copy link
Copy Markdown
Collaborator

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
@pelikhan
pelikhan merged commit ebf15ee into main Sep 4, 2026
32 checks passed
@pelikhan
pelikhan deleted the copilot/sighthound-fix-security-findings branch September 4, 2026 21:04
Sign up for free to 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