Skip to content

[Vulnerability] github/github-mcp-server: Time-of-Check-Time-of-Use (TOCTOU) Race Condition #90

Open

Description

@github-actions

Potential Security Vulnerability Detected

Repository: github/github-mcp-server
Commit: b8f107b
Author: Jorge Costa
Date: 2026-09-01T13:12:25Z

Commit Message

Add expectedHeadSha pinning to merge_pull_request (#3182)

* Add head SHA pinning to merge_pull_request

* Update merge_pull_request generated documentation

* test(pull-requests): harden merge SHA pinning

Make the schema and unpinned compatibility coverage explicit, and verify stale-head conflicts surface without a retry.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Sam Morrow <sammorrowdrums@github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Pull Request

PR: #3182 - Add expectedHeadSha pinning to merge_pull_request
Labels: None

Description:

Summary

Adds optional expectedHeadSha pinning to merge_pull_request.

The value is forwarded to github.PullRequestOptions.SHA, which
go-github serializes as the GitHub REST merge endpoint's optional
sha field.

This closes the TOCTOU gap between reviewing a pull request HEAD and merging
it: if the HEAD changes, GitHub rejects the merge instead of merging the new
commit.

Changes

  • add optional expectedHeadSha to the merge_pull_request schema;
  • pass it to `PullRequestOption...

Analysis

Vulnerability Type: Time-of-Check-Time-of-Use (TOCTOU) Race Condition
Severity: High

Description

The merge_pull_request function had a TOCTOU vulnerability where the pull request HEAD could be modified between when a user reviewed it and when the merge was executed. An attacker could change the PR's HEAD after approval but before merge, causing unreviewed code to be merged. The patch adds optional expectedHeadSha pinning that validates the HEAD hasn't changed before merging, closing this race condition gap.

Affected Code

options := &github.PullRequestOptions{
    CommitTitle: commitTitle,
    MergeMethod: mergeMethod,
}
// No SHA validation before merge

Proof of Concept

1. User reviews PR #42 with HEAD SHA abc123...
2. Attacker pushes malicious commit to PR, changing HEAD to def456...
3. User calls merge_pull_request without expectedHeadSha parameter
4. Malicious code at def456... gets merged without review

With patch:
User calls merge_pull_request with expectedHeadSha='abc123...'
If attacker changed HEAD to def456..., GitHub returns 409 Conflict
Merge fails and operator must explicitly re-review before retrying

This issue was automatically created by Vulnerability Spoiler Alert.
Detected at: 2026-10-06T08:38:02.928Z

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

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions