Skip to content

feat(controls): ship pull-request-target-with-head-checkout (ISSUE-804)#190

Open
stephrobert wants to merge 1 commit into
getplumber:mainfrom
stephrobert:feat/ship-prtarget-head-checkout
Open

feat(controls): ship pull-request-target-with-head-checkout (ISSUE-804)#190
stephrobert wants to merge 1 commit into
getplumber:mainfrom
stephrobert:feat/ship-prtarget-head-checkout

Conversation

@stephrobert
Copy link
Copy Markdown
Contributor

What

Promotes pullRequestTargetMustNotCheckoutHead (rule
pull-request-target-with-head-checkout, ISSUE-804, severity
critical) from the dev bench to a shipping GitHub control.

Why

The control flags the tj-actions / CVE-2025-30066 vector: a workflow
triggered by pull_request_target that checks out the pull-request
head, placing base-repo secrets and fork-controlled code in the same
run.

How

  • Un-benched in configuration/registry.go; wired through
    plumberconfig (validation schema + typed struct), control/catalog.go,
    control/mrcomment.go, the config init wizard and .plumber.yaml.
  • The rule now abstains when the job carries an if: guard that
    restricts execution to same-repository pull requests
    (head.repo.full_name == github.repository, or a head.repo.fork
    check). Fork-controlled code never runs under such a guard, so
    flagging the job would be a false positive.

Validation

  • TestIssue415 extended to 5 cases (2 violations, 3 clean — including
    the fork-guard case).
  • make build && make test && make lint all green.
  • Swept 20 popular OSS repositories: the only ISSUE-804 hit
    (sveltejs/svelte) is a guarded job — correctly silenced by the
    guard exclusion, while the unguarded head-checkout fixtures still
    fire.

Closes #181

Promote pullRequestTargetMustNotCheckoutHead out of the dev bench:
registry, plumberconfig (schema + struct), catalog, MR-comment
ordering, the `config init` wizard and .plumber.yaml are all wired
so the control ships enabled.

The rule now abstains when the job carries an `if:` guard that
restricts execution to same-repository pull requests
(`head.repo.full_name == github.repository`, or a `head.repo.fork`
check). Fork-controlled code never runs under such a guard, so the
exploit does not apply. Without this, a correctly mitigated workflow
was reported critical.

Verified against a sweep of 20 popular OSS repositories: the single
ISSUE-804 hit (sveltejs/svelte) is a guarded job and is now correctly
silenced, while the unguarded head-checkout fixtures still fire.

Closes getplumber#181
@thomasboni
Copy link
Copy Markdown
Contributor

Thanks for the PR @stephrobert! We'll review it ASAP.

@Joseph94m
Copy link
Copy Markdown
Collaborator

Will handle this tomorrow

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(controls): ship pull-request-target-with-head-checkout (ISSUE-804)

3 participants