[code-scanning-fix] Fix REST API path injection in ghAPIGet/ghAPIGetArray (alerts #641, #642)#45400
Conversation
…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>
|
🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅ |
|
✅ PR Code Quality Reviewer completed the code quality review. |
|
✅ 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. |
|
✅ 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). |
There was a problem hiding this comment.
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
escapeOwnerRepoto URL-path-escapeownerandrepocomponents independently. - Updated
ghAPIGetandghAPIGetArrayto use the escapedowner/repowhen constructingrepos/{owner}/{repo}/{endpoint}REST paths. - Added
net/urlimport to supporturl.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
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Skills-Based Review 🧠
Applied /diagnosing-bugs and /tdd — commenting on a missing regression test.
📋 Key Themes & Highlights
Key Themes
- Missing regression tests:
escapeOwnerRepois 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/repocomponent 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
ghAPIGetandghAPIGetArrayare 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
|
@copilot Run pr-finisher skill |
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Ran pr-finisher workflow and pushed follow-up fixes in Implemented endpoint validation in |
|
@copilot please run the
|
Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
Completed. The three referenced threads are now resolved, and the endpoint sanitization + regression tests were added in I also reran local checks on the current head ( |
Summary
Fixes REST API path injection vulnerabilities (code scanning alerts #641, #642) in
ghAPIGetandghAPIGetArrayby URL-path-encoding theowner/repocomponents and validating the endpoint string before constructinggh apicalls.Changes
pkg/cli/outcome_eval.goescapeOwnerRepo(ownerRepo string) string— splitsowner/repoon the first/and appliesurl.PathEscapeto each component independently, neutralising path-traversal sequences and pre-encoded slashes.validateAPIEndpoint(endpoint string) error— rejects endpoints that start with/or contain..path segments.ghAPIGetandghAPIGetArraynow callvalidateAPIEndpointbefore use and callescapeOwnerRepowhen formatting therepos/<owner>/<repo>/<endpoint>URL path passed togh api.pkg/cli/outcome_eval_test.goTestEscapeOwnerRepo— 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.mdconfigure-agentic-engine.mdto the list of context files the skill loads.Security impact
Before this fix, a maliciously crafted
owner/repovalue 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
TestNormalizeRepoForAPIsuite unchanged.