Skip to content

[code-scanning-fix] Fix REST API path injection in ghAPIGet/ghAPIGetArray (alerts #641, #642)#45400

Merged
pelikhan merged 3 commits into
mainfrom
fix/code-scanning-641-642-rest-path-injection-403304c678a7b29a
Jul 14, 2026
Merged

[code-scanning-fix] Fix REST API path injection in ghAPIGet/ghAPIGetArray (alerts #641, #642)#45400
pelikhan merged 3 commits into
mainfrom
fix/code-scanning-641-642-rest-path-injection-403304c678a7b29a

Conversation

@github-actions

@github-actions github-actions Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes REST API path injection vulnerabilities (code scanning alerts #641, #642) in ghAPIGet and ghAPIGetArray by URL-path-encoding the owner/repo components and validating the endpoint string before constructing gh api calls.

Changes

pkg/cli/outcome_eval.go

  • escapeOwnerRepo(ownerRepo string) string — splits owner/repo on the first / and applies url.PathEscape to each component independently, neutralising path-traversal sequences and pre-encoded slashes.
  • validateAPIEndpoint(endpoint string) error — rejects endpoints that start with / or contain .. path segments.
  • Both ghAPIGet and ghAPIGetArray now call validateAPIEndpoint before use and call escapeOwnerRepo when formatting the repos/<owner>/<repo>/<endpoint> URL path passed to gh api.

pkg/cli/outcome_eval_test.go

  • TestEscapeOwnerRepo — 4 table-driven cases: normal repo, traversal in repo segment, pre-encoded slash neutralisation, no-slash fallback.
  • TestValidateAPIEndpoint — 3 table-driven cases: relative endpoint (allowed), leading slash (rejected), .. segment (rejected).

.github/skills/agentic-workflows/SKILL.md

  • Added configure-agentic-engine.md to the list of context files the skill loads.

Security impact

Before this fix, a maliciously crafted owner/repo value could inject extra path segments into the GitHub REST API URL (e.g. owner/../admin/...). The new encoding and validation close both the path-traversal and the leading-slash injection vectors.

Testing

Unit tests added for both new helpers; existing TestNormalizeRepoForAPI suite unchanged.

Generated by PR Description Updater for #45400 · 28.2 AIC · ⌖ 6.87 AIC · ⊞ 4.7K ·

…ection

Alerts #641 and #642 flagged that ownerRepo (derived from user-supplied
repo input) was interpolated into GitHub REST API paths via fmt.Sprintf
without URL-path encoding. A crafted repo string containing '..', '%2F',
or other special characters could alter the API path.

Fix: add escapeOwnerRepo() which applies url.PathEscape to each component
of the 'owner/repo' pair before interpolation in ghAPIGet and ghAPIGetArray.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions

github-actions Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor Author

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

@github-actions

github-actions Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor Author

PR Code Quality Reviewer completed the code quality review.

@github-actions

github-actions Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor Author

Test Quality Sentinel completed test quality analysis.

No test files were added or modified in this PR. Test Quality Sentinel skipped. This PR modifies only pkg/cli/outcome_eval.go (production code for REST API path injection fixes #641, #642) without any corresponding test changes.

@github-actions

github-actions Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor Author

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

No ADR enforcement needed: PR #45400 does not have the 'implementation' label and has only 13 new lines of code in business logic directories (threshold: 100).

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.

Pull request overview

This PR addresses code-scanning findings by preventing user-influenced owner/repo strings from being interpolated into gh api REST paths without URL path encoding in the outcome evaluation CLI.

Changes:

  • Added escapeOwnerRepo to URL-path-escape owner and repo components independently.
  • Updated ghAPIGet and ghAPIGetArray to use the escaped owner/repo when constructing repos/{owner}/{repo}/{endpoint} REST paths.
  • Added net/url import to support url.PathEscape.
Show a summary per file
File Description
pkg/cli/outcome_eval.go Escapes owner/repo components before building gh api REST paths for outcome evaluation queries.

Review details

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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

Comment thread pkg/cli/outcome_eval.go
Comment thread pkg/cli/outcome_eval.go

@github-actions github-actions Bot left a comment

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.

The fix correctly addresses the REST API path injection vulnerability. escapeOwnerRepo properly splits on / and applies url.PathEscape to each component independently, neutralizing path traversal sequences without affecting valid repo strings.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · 13.7 AIC · ⌖ 7.54 AIC · ⊞ 4.8K

@github-actions github-actions Bot mentioned this pull request Jul 14, 2026

@github-actions github-actions Bot left a comment

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.

Review: Path Injection Fix (alerts #641, #642)

Fix is correct — URL-path-encoding each component of ownerRepo separately is the right approach and addresses the stated alerts.

⚠️ Residual gap: endpoint is still interpolated unescaped

Both ghAPIGet and ghAPIGetArray escape ownerRepo but leave endpoint raw in the same fmt.Sprintf call:

args := []string{"api", fmt.Sprintf("repos/%s/%s", escapeOwnerRepo(ownerRepo), endpoint)}

All current callers construct endpoint with %d integer formatting (e.g. "issues/%d") or short hardcoded paths, so there is no exploitable path today. However, the function signature accepts an arbitrary string, making future callers or refactors a latent injection risk.

Consider either documenting the contract (endpoint must be a validated/hardcoded path segment) or applying url.PathEscape per segment to endpoint as well.

🔎 Code quality review by PR Code Quality Reviewer · 27.6 AIC · ⌖ 4.34 AIC · ⊞ 5.4K
Comment /review to run again

@github-actions github-actions Bot left a comment

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.

Skills-Based Review 🧠

Applied /diagnosing-bugs and /tdd — commenting on a missing regression test.

📋 Key Themes & Highlights

Key Themes

  • Missing regression tests: escapeOwnerRepo is the security-critical new helper but has no unit tests. A bad refactor could silently reintroduce the vulnerability.

Positive Highlights

  • ✅ Root cause is correctly addressed: each owner/repo component is individually URL-path-encoded, preserving the / separator.
  • ✅ Fallback for a no-slash input is a sensible defensive default.
  • ✅ Fix is minimal and surgical — no unnecessary scope creep.
  • ✅ Both ghAPIGet and ghAPIGetArray are consistently updated.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · 25.3 AIC · ⌖ 6.92 AIC · ⊞ 6.6K
Comment /matt to run again

Comment thread pkg/cli/outcome_eval.go
@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot Run pr-finisher skill

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

@copilot Run pr-finisher skill

Ran pr-finisher workflow and pushed follow-up fixes in 60188f8.

Implemented endpoint validation in ghAPIGet/ghAPIGetArray (reject leading / and .. segments), added regression tests for escapeOwnerRepo and endpoint validation, and re-ran local validation + parallel validation.

Copilot AI requested a review from pelikhan July 14, 2026 10:37
@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot please run the pr-finisher skill, address the unresolved review feedback, and rerun checks. Prioritize these unresolved threads first (newest first):

Generated by 👨‍🍳 PR Sous Chef · 8.61 AIC · ⌖ 8.24 AIC · ⊞ 5.1K ·
Comment /souschef to run again

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

Copilot AI commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

@copilot please run the pr-finisher skill, address the unresolved review feedback, and rerun checks. Prioritize these unresolved threads first (newest first):

Completed. The three referenced threads are now resolved, and the endpoint sanitization + regression tests were added in 60188f8.

I also reran local checks on the current head (7ea16ea): make fmt, make lint, make test, and parallel_validation (clean). Current GitHub workflow runs for this head are action_required with no jobs started, so a maintainer will need to re-trigger CI.

Copilot AI requested a review from gh-aw-bot July 14, 2026 11:31
@pelikhan pelikhan merged commit b5cb3e5 into main Jul 14, 2026
@pelikhan pelikhan deleted the fix/code-scanning-641-642-rest-path-injection-403304c678a7b29a branch July 14, 2026 11:44
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.

4 participants