-
Notifications
You must be signed in to change notification settings - Fork 32
fix: add missing Checkout-GhAwPr.ps1 script #788
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| #!/usr/bin/env pwsh | ||
| # Checkout-GhAwPr.ps1 — Security-checked PR checkout for gh-aw workflow_dispatch. | ||
| # | ||
| # Verifies the PR author has write access to the repo, checks out the PR branch, | ||
| # then restores .github/ from the base branch (main) to prevent prompt injection | ||
| # via modified workflow files in the PR. | ||
|
|
||
| $ErrorActionPreference = 'Stop' | ||
|
|
||
| $prNumber = $env:PR_NUMBER | ||
| if (-not $prNumber) { | ||
| Write-Error "PR_NUMBER environment variable is required" | ||
| exit 1 | ||
| } | ||
|
|
||
| Write-Host "Checking out PR #$prNumber..." | ||
|
|
||
| # Get PR info | ||
| $prJson = gh pr view $prNumber --json headRefName,headRepository,headRepositoryOwner,author,baseRefName --repo $env:GITHUB_REPOSITORY 2>&1 | ||
| if ($LASTEXITCODE -ne 0) { | ||
| Write-Error "Failed to get PR #$prNumber info: $prJson" | ||
| exit 1 | ||
| } | ||
| $pr = $prJson | ConvertFrom-Json | ||
|
|
||
| $branch = $pr.headRefName | ||
| $baseBranch = $pr.baseRefName | ||
| $author = $pr.author.login | ||
|
|
||
| Write-Host "PR #$prNumber by $author, branch: $branch, base: $baseBranch" | ||
|
|
||
| # Check author has write access (skip for bots) | ||
| if ($author -notmatch '\[bot\]$') { | ||
| $permJson = gh api "repos/$($env:GITHUB_REPOSITORY)/collaborators/$author/permission" --jq '.permission' 2>&1 | ||
| if ($LASTEXITCODE -ne 0) { | ||
| Write-Warning "Could not verify author permissions: $permJson" | ||
| } else { | ||
| $perm = $permJson.Trim() | ||
| if ($perm -notin @('admin', 'maintain', 'write')) { | ||
| Write-Error "Author '$author' has '$perm' permission — write access required for workflow_dispatch review" | ||
| exit 1 | ||
| } | ||
| Write-Host "Author '$author' has '$perm' access — OK" | ||
| } | ||
| } | ||
|
|
||
| # Fetch and checkout the PR branch | ||
| git fetch origin "pull/$prNumber/head:pr-$prNumber" 2>&1 | Write-Host | ||
| git checkout "pr-$prNumber" 2>&1 | Write-Host | ||
|
|
||
| # Save the PR HEAD SHA | ||
| $prSha = git rev-parse HEAD | ||
| Write-Host "PR HEAD: $prSha" | ||
|
|
||
| # Restore .github/ from the base branch to prevent workflow tampering | ||
| Write-Host "Restoring .github/ from $baseBranch..." | ||
| git checkout "origin/$baseBranch" -- .github/ 2>&1 | Write-Host | ||
|
Comment on lines
+48
to
+57
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 CRITICAL · 3/3 reviewers ·
Fix: Check git fetch origin "pull/$prNumber/head:pr-$prNumber" 2>&1 | Write-Host
if ($LASTEXITCODE -ne 0) { Write-Error "git fetch failed"; exit 1 }
git checkout "pr-$prNumber" 2>&1 | Write-Host
if ($LASTEXITCODE -ne 0) { Write-Error "git checkout failed"; exit 1 }
# ... same for line 57's .github/ restore
git checkout "origin/$baseBranch" -- .github/ 2>&1 | Write-Host
if ($LASTEXITCODE -ne 0) { Write-Error ".github/ restore failed"; exit 1 }Alternatively, use
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 MODERATE · 3/3 reviewers · The script only fetches Fix: Fetch the base ref before restoring (prefer immutable SHA via # Add baseRefOid to the gh pr view --json fields
$baseSha = $pr.baseRefOid
git fetch origin $baseSha 2>&1 | Write-Host
if ($LASTEXITCODE -ne 0) { Write-Error "Failed to fetch base ref"; exit 1 }
git checkout $baseSha -- .github/ 2>&1 | Write-Host
if ($LASTEXITCODE -ne 0) { Write-Error "Failed to restore .github/"; exit 1 } |
||
|
|
||
| Write-Host "Checkout complete — PR #$prNumber on branch $branch, .github/ from $baseBranch" | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔴 CRITICAL · 3/3 reviewers · Permission check fail-open — API failure silently bypasses access gate
The collaborators API returns HTTP 404 for non-collaborators (the exact users this gate should block). When
$LASTEXITCODE -ne 0, the script logs aWrite-Warningand continues — the checkout proceeds without any authorization check. This also triggers on rate limits, insufficient token scope, or network errors.Scenario: A fork PR author with read-only access triggers
workflow_dispatch. The API returns 404, the warning is logged and ignored, and the untrusted PR is checked out and reviewed.Fix: Fail closed — treat API failure as denied: