Skip to content

Fork-PR security gate has never started: the pull_request_target event is refused by Actions policy (30/30 startup_failure)聽#1102

Description

@hyperpolymath

Finding

馃敶 GATE: Security Gate (Fork PRs) (.github/workflows/security-gate-pr-target.yml) has never started on any PR in the most recent page of its runs. All 30 of 30 runs on actions/workflows/security-gate-pr-target.yml/runs?per_page=30, from 2026-09-30T14:07Z to 23:00Z, ended in startup_failure with zero jobs. 30 is the page size, so the real total is at least 30.

The startup text on run 36788265205 (PR #1088 head 6192c92d) says:

Event 'pull_request_target' is not allowed to trigger Actions workflows. Workflow file: '.github/workflows/security-gate-pr-target.yml'.

This is not a parse defect. #997 (2026-09-22) fixed an empty-expression parse error in this file, and the file on main@3238461b parses. The Actions policy refuses the trigger itself. GET repos/hyperpolymath/standards/actions/permissions returns only enabled, allowed_actions, selected_actions_url and sha_pinning_required, with no event field. That call does not show which setting does the refusing, and this issue does not guess.

Not a merge blocker: the gate's contexts are not among the 21 required status checks on main. Filed under the 2026-09-15 stopping rule (a new finding is an issue, not a blocker).

Scope of this observation

  • A local scan of hyper-repos/ and meta-repos/ (601 .github/workflows directories) found pull_request_target in 9 files across 7 checkouts. Only standards is estate-authored. The other six are third-party forks under _OPM, a bounty fork, an esoteric-set repo, or a duplicate standards checkout.
  • Bounded: local clones can be stale, so this does not prove that no other estate repo carries the trigger on GitHub.

Recommended cure (elegance arm, OWASP D223)

Move the gate from pull_request_target to pull_request:

  • pull_request_target is the "pwn request" class: fork-controlled content handled with a base-context token. The file's own comments already spend about 20 lines defending against it. The policy that refuses the event matches the estate's OWASP-safe ruling, so the gate should change, not the policy.
  • On pull_request, a fork PR gets a read-only token and no secrets. The gate only statically scans the diff, so it needs nothing more.
  • Replace the actions/github-script PR comment, which needs pull-requests: write, with ::error:: annotations and a job summary, and fail the job on findings.
  • The PR's own copy of the workflow will then run, not the base copy. That is acceptable for a non-required advisory scan. If it is ever made required, record that trade-off in the same PR.

The alternative arm, re-enabling pull_request_target wherever the policy lives, widens the attack surface and conflicts with D223. It needs an owner ruling.

Acceptance criteria

  1. security-gate-pr-target.yml (renamed if appropriate) runs with jobs > 0 on at least three consecutive PRs, measured on actions/workflows/<file>/runs, not inferred from the check rollup, which cannot see startup_failure.
  2. Planted positive control: a test PR (or a fixture exercised by the self-test suite) containing content the malicious-content scan must flag turns the gate red. A gate that cannot go red is not a gate.
  3. No pull_request_target remains in standards/.github/workflows/, or, if the owner rules for re-enabling it, the PR records where the setting lives with a before/after read of it.
  4. The job's permissions: block grants no write scope.
  5. The rsr template and any estate copy of this gate are propagated in the same campaign ("settle in standards, then propagate").

馃 Generated with Claude Code

https://claude.ai/code/session_01QYY8Gp4v4x2J7iSNn1vZ57

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions