security: document intentional absence of PR head ref in pull_request_target checkouts - #855
Open
kmarekspartz wants to merge 2 commits into
Open
Conversation
Merge in upstream
|
|
kmarekspartz
had a problem deploying
to
inkeep-oss-sync
July 28, 2026 18:31 — with
GitHub Actions
Error
|
Thanks for the contribution! What happens next:
|
kmarekspartz
requested a deployment
to
inkeep-oss-sync
July 28, 2026 18:32 — with
GitHub Actions
Waiting
Contributor
Author
|
Given this isn't directly exploitable but more of a preventative comment, I did not go through the security process. Let me know if I should have! |
Contributor
|
thanks, i have a todo to bump to v7 and will address this too |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
pull_request_targetruns in the base-branch context with full access to repository secrets. Addingref: ${{ github.event.pull_request.head.sha }}to either checkout in thesyncorclosejobs would allow a PR author's scripts to execute withOSS_SYNC_APPcredentials — enabling reads/writes to `inkeep/agents-privateHow this was verified
Good news:
The current code appears safe: the missing
ref:is intentional, and a contributor of a PR adding aref:could not self-exploit. This PR makes that intent explicit with a comment so future reviewers recognize a PR adding that line as a security regression rather than a neutral cleanup.pull_request_target always runs the base branch's version of the workflow file, never the PR head's. So if an attacker submits a PR that adds ref:
${{ github.event.pull_request.head.sha }}to the checkout in monorepo-pr-bridge.yml, that PR runs the current (safe) workflow — the ref: change has no effect until someone merges it.Threat model
A potential attack chain would require two steps:
Social engineering merge: The attacker submits a PR adding ref: ${{ github.event.pull_request.head.sha }} to the sync job's checkout, framed innocuously — e.g., "check out PR code to improve diff logging." A reviewer who doesn't deeply understand the pull_request_target security model sees a one-line workflow tweak and merges it.
Exploit via a second PR: Now the base branch has the vulnerable workflow. The attacker (or anyone) opens a new PR. When a maintainer approves the inkeep-oss-sync environment — which they'd routinely do for legitimate-looking PRs — the workflow now checks out the PR head's code AND has secrets. The attacker's malicious version of .github/scripts/bridge-public-pr-to-monorepo.mjs runs with full access to OSS_SYNC_APP_ID and OSS_SYNC_APP_PRIVATE_KEY.
What could those credentials do?
The App token is minted with access to inkeep/agents-private. Based on the workflow, it has at minimum contents: write on that repo. An attacker could:
Changes
.github/workflows/monorepo-pr-bridge.yml— adds aSECURITY:comment above theactions/checkoutstep in both thesyncandclosejobs explaining whyref: ${{ github.event.pull_request.head.sha }}must not be added thereChecklist
pnpm check(lint, typecheck, tests) locallypnpm changeset) if this changes behaviorAfter you open this PR
See CONTRIBUTING.md for details.