Skip to content

fix(ci): stop trusting a merge queue title from a fork - #1881

Merged
mergify[bot] merged 1 commit into
mainfrom
devs/sileht/mrgfy-8854-mq-title-spoofing/stop-trusting-merge-queue-title-fork--19f70a5d
Oct 5, 2026
Merged

mergify[bot] merged 1 commit into
mainfrom
devs/sileht/mrgfy-8854-mq-title-spoofing/stop-trusting-merge-queue-title-fork--19f70a5d

Conversation

@sileht

@sileht sileht commented Oct 5, 2026

Copy link
Copy Markdown
Member

mergify ci git-refs and ci scopes read a pull request body as the
engine's merge queue metadata on the title prefix merge queue: alone.
The title is the author's to pick, so a fork's pull request could name
its own head as checking_base_sha: the diff came out empty, every scope
read false, and source: merge_queue force-enabled the merge-queue
scope, with CI green. pull_request_target runs that path too.

The engine always opens its drafts from a branch of the base repository,
so merge queue metadata is now only read when the pull request's head
and base live in the same repository (compared by id). That gates the
git note as well as the body: a workflow that checks a fork out as
origin fetches the fork's note, which the fork's author writes. A fork,
a deleted fork's head, or a payload without repository ids falls through
to the pull request base, with a warning when the title asked for the
body.

What this does not close: anyone who can read the repository can open a
pull request from a branch someone else pushed there and write its title
and body. The code under test is then still a writer's.

The other signals the ticket listed do not hold up: the branch prefix is
queue_branch_prefix and the author is draft_bot_account, both
configurable. Dropping the body path for the git note only was rejected
too: the engine writes the note best effort and swallows push failures,
and a clone that cannot fetch notes would lose the merge-queue scope on
every draft.

Fixes MRGFY-8854

Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com

`mergify ci git-refs` and `ci scopes` read a pull request body as the
engine's merge queue metadata on the title prefix `merge queue: ` alone.
The title is the author's to pick, so a fork's pull request could name
its own head as `checking_base_sha`: the diff came out empty, every scope
read false, and `source: merge_queue` force-enabled the merge-queue
scope, with CI green. `pull_request_target` runs that path too.

The engine always opens its drafts from a branch of the base repository,
so merge queue metadata is now only read when the pull request's head
and base live in the same repository (compared by id). That gates the
git note as well as the body: a workflow that checks a fork out as
`origin` fetches the fork's note, which the fork's author writes. A fork,
a deleted fork's head, or a payload without repository ids falls through
to the pull request base, with a warning when the title asked for the
body.

What this does not close: anyone who can read the repository can open a
pull request from a branch someone else pushed there and write its title
and body. The code under test is then still a writer's.

The other signals the ticket listed do not hold up: the branch prefix is
`queue_branch_prefix` and the author is `draft_bot_account`, both
configurable. Dropping the body path for the git note only was rejected
too: the engine writes the note best effort and swallows push failures,
and a clone that cannot fetch notes would lose the merge-queue scope on
every draft.

Fixes MRGFY-8854

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Change-Id: I19f70a5d13a2672ad13b1a4d66f54d132c3ad32e
Copilot AI balanced review requested due to automatic review settings October 5, 2026 14:15
@mergify

mergify Bot commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Merge Protections

🟢 All 6 merge protections satisfied — ready to merge.

Show 6 satisfied protections

🟢 🤖 Continuous Integration

  • all of:
    • check-success=ci-gate

🟢 👀 Review Requirements

  • any of:
    • #approved-reviews-by>=2
    • author = dependabot[bot]
    • author = mergify-ci-bot
    • author = renovate[bot]

🟢 Enforce conventional commit

Make sure that we follow https://www.conventionalcommits.org/en/v1.0.0/

  • title ~= ^(fix|feat|internal|docs|style|refactor|perf|test|build|ci|chore|revert|ui)(?:\(.+\))?!?:

🟢 🔎 Reviews

  • #changes-requested-reviews-by = 0
  • #review-requested = 0
  • #review-threads-unresolved = 0

🟢 📕 PR description

  • body ~= (?ms:.{48,})

🟢 🚦 Auto-queue

When all merge protections are satisfied, this pull request will be queued automatically.

@mergify
mergify Bot deployed to Mergify Merge Protections October 5, 2026 14:15 Active
@sileht
sileht deployed to func-tests-live October 5, 2026 14:15 — with GitHub Actions Active

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟢 Approval recommended

The repository-origin gate consistently covers both metadata sources with appropriate fallback behavior and focused tests.

Review effort: Balanced
Findings: None

What changed in this PR

Hardens merge-queue metadata detection by trusting only pull requests whose head and base repository IDs match.

Changes:

  • Adds repository identity data and same-repository validation.
  • Gates body and git-note metadata extraction.
  • Adds regression coverage for forked and missing-repository payloads.
File Description
queue_metadata.rs Rejects untrusted metadata bodies.
github_event.rs Models repository IDs and validates origin.
git_refs.rs Gates git notes and adds security regression tests.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@sileht
sileht marked this pull request as ready for review October 5, 2026 14:18
@mergify
mergify Bot requested a review from a team October 5, 2026 14:34
@mergify
mergify Bot requested a review from a team October 5, 2026 14:53
@mergify

mergify Bot commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Merge Queue Status

This pull request spent 9 minutes 21 seconds in the queue, including 8 minutes 53 seconds running CI.

Required conditions to merge

@mergify mergify Bot added the queued label Oct 5, 2026
@mergify
mergify Bot merged commit 98a81e4 into main Oct 5, 2026
42 of 44 checks passed
@mergify
mergify Bot deleted the devs/sileht/mrgfy-8854-mq-title-spoofing/stop-trusting-merge-queue-title-fork--19f70a5d branch October 5, 2026 15:13
@mergify mergify Bot removed the queued label Oct 5, 2026

This branch was successfully deployed

2 active deployments
func-tests-live — 36e518e4 Deployed Oct 5, 2026 by sileht via live-tests #1973
Mergify Merge Protections — 36e518e4 Deployed Oct 5, 2026 by mergify[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants