Summary
Pre-existing shell-injection surface in lib/adapters/pr-wait-ci-github.ts. The repoFlag helper interpolates repo raw into the shell command string:
function repoFlag ( repo : string | undefined ) : string {
return repo !== undefined ? ` --repo ${ repo } ` : '' ;
}
The result is concatenated into commands like gh pr view ${number} --json statusCheckRollup,url${repoFlag(repo)} and passed to exec() (which calls execSync directly).
This is the same injection class as PR #403 /#407 .
Active exploitability: Mitigated by repoOptionalSchema (regex blocks shell metacharacters at the handler boundary). This is a defence-in-depth fix.
Implementation Steps
Update lib/adapters/pr-wait-ci-github.ts. Two options:
Option A (minimal): import shellEscape and wrap the value:
import { shellEscape } from '../shared/shell-escape.js' ;
function repoFlag ( repo : string | undefined ) : string {
return repo !== undefined ? ` --repo ${ shellEscape ( repo ) } ` : '' ;
}
Option B (preferred): migrate the call site to use runArgv (argv-array form) instead of string-template + exec(). Same pattern as PR fix(security): eliminate shell injection in pr_merge GraphQL fallback #403 's fix in pr-merge-github.ts.
Add a regression test in lib/adapters/pr-wait-ci-github.test.ts (or wherever this adapter is tested) injecting a hostile repo value.
Test Procedures
Run existing tests for pr-wait-ci-github.ts — all should pass.
Inject hostile repo value, verify no breakout.
Run full suite — confirm no regressions.
Acceptance Criteria
Dependencies
Metadata
Field
Value
Repository
Wave-Engineering/mcp-server-sdlc
Surfaced by
code-reviewer trust-score gate (plan #390 audit byproduct)
Summary
Pre-existing shell-injection surface in
lib/adapters/pr-wait-ci-github.ts. TherepoFlaghelper interpolatesreporaw into the shell command string:The result is concatenated into commands like
gh pr view ${number} --json statusCheckRollup,url${repoFlag(repo)}and passed toexec()(which callsexecSyncdirectly).This is the same injection class as PR #403/#407.
Active exploitability: Mitigated by
repoOptionalSchema(regex blocks shell metacharacters at the handler boundary). This is a defence-in-depth fix.Implementation Steps
Update
lib/adapters/pr-wait-ci-github.ts. Two options:Option A (minimal): import
shellEscapeand wrap the value:Option B (preferred): migrate the call site to use
runArgv(argv-array form) instead of string-template +exec(). Same pattern as PR fix(security): eliminate shell injection in pr_merge GraphQL fallback #403's fix inpr-merge-github.ts.Add a regression test in
lib/adapters/pr-wait-ci-github.test.ts(or wherever this adapter is tested) injecting a hostilerepovalue.Test Procedures
pr-wait-ci-github.ts— all should pass.repovalue, verify no breakout.Acceptance Criteria
pr-wait-ci-github.ts:repoFlagshell-escapesrepo(or migrates torunArgv)lib/adapters/for the same${repo}interpolation pattern (light grep) and either fix or document any others foundDependencies
Metadata