GitHub Enterprise Server – Authorization Bypass via Auto-Merge
CVE ID: CVE-2026-1999
Product: GitHub Enterprise Server (GHES)
Vulnerability Type: Authorization Bypass / Improper Access Control
CWE: CWE-863 – Incorrect Authorization
CVSS v3.1 Score: 7.5 (High)
Attack Vector: Network
Attack Complexity: Low
Privileges Required: None (in specific repository configurations)
User Interaction: None
Scope: Unchanged
Impact: Integrity High, Confidentiality None, Availability None
Exploit Availability: No public weaponized exploit at time of disclosure
Exploitability: Conditional – depends on repository configuration (forks enabled, no branch protection, PR in clean state)
Affected Versions: GitHub Enterprise Server prior to 3.19.2, 3.18.5, 3.17.11
Fixed Versions: 3.19.2 / 3.18.5 / 3.17.11
Overview
An authorization bypass vulnerability was identified in GitHub Enterprise Server involving the GraphQL mutation responsible for enabling auto-merge on pull requests. Under specific repository conditions, the required permission validation was not consistently enforced when the enable_auto_merge operation was executed.
Because of this flaw, it was possible for a user without push or write access to cause their own pull request—originating from a forked repository—to be merged automatically into the target repository.
The issue did not affect all deployments. Exploitation depended heavily on repository configuration and workflow controls.
Technical Description
GitHub Enterprise Server supports automatic merging of pull requests once all required checks pass. This behavior is controlled by a GraphQL mutation commonly referred to as enable_auto_merge.
During normal operation:
- Only users with appropriate repository permissions (write/maintain/admin) should be able to enable auto-merge.
- Branch protection rules should enforce required reviews and status checks.
- Permission validation should occur before toggling merge eligibility.
In vulnerable versions:
- The authorization check was not enforced in every code path when the mutation was invoked.
- Under certain states, the server accepted the auto-merge request even when the initiating actor lacked required repository privileges.
- Once all status checks were satisfied and no branch protections blocked the action, the pull request was merged automatically.
The flaw existed in the permission validation logic rather than in merge mechanics themselves.
Conditions Required for Exploitation
The vulnerability was not universally exploitable. All of the following conditions needed to be true:
- The target repository allowed forks.
- The attacker created a fork and opened a pull request.
- The pull request reached a “clean” state (all required checks passed).
- The target branch had no branch protection rules preventing auto-merge.
- The attacker triggered the auto-merge mutation via GraphQL.
If branch protection rules were enabled requiring approvals or restricting who could merge, exploitation would not succeed.
Impact
If successfully exploited, the vulnerability allowed unauthorized code to be merged into a repository.
Potential consequences included:
- Introduction of malicious code or backdoors
- Modification of CI/CD workflows
- Exposure of secrets via workflow changes
- Dependency poisoning
- Supply chain compromise in automated deployments
The vulnerability impacted integrity only. It did not provide direct server-side code execution or appliance-level compromise.
However, indirect compromise could occur if merged code triggered automated deployment pipelines.
Exploitation Scenario (Educational)
The following high-level scenario illustrates how the issue could have been abused:
- A fork of a public/internal repository was created.
- A pull request containing seemingly legitimate changes was submitted.
- Status checks were allowed to complete successfully.
- A crafted GraphQL mutation was sent to enable auto-merge.
- Due to missing permission validation, the request was accepted.
- Once checks passed, the pull request merged automatically.
Example mutation structure for detection awareness:
mutation {
enableAutoMerge(input: {pullRequestId: "PR_NODE_ID"}) {
pullRequest {
autoMergeRequest {
enabledAt
}
}
}
}
No public exploit toolkit or automated weaponized PoC has been observed. Exploitation would require knowledge of repository configuration and GraphQL interaction.
MITRE ATT&CK Mapping
- TA0001 – Initial Access
- T1195 – Supply Chain Compromise
- T1556 – Modify Authentication Process
- T1098 – Account Manipulation
- T1078 – Valid Accounts
- T1485 – Data Manipulation
Primary mapping:
CWE-863 – Incorrect Authorization
Indicators of Compromise
The following behavioral indicators may suggest exploitation:
- Pull requests merged where the author lacks write permission.
- Auto-merge enabled by a user without merge privileges.
- GraphQL mutation calls for
enable_auto_mergefrom non-collaborator accounts. - Merges occurring immediately after status checks pass without human approval.
- Unusual merges from forked repositories into sensitive branches.
Log Sources for Detection
The following log sources should be monitored:
- GitHub Enterprise Audit Logs
- GraphQL API access logs
- Webhook delivery logs
- Pull request event logs
- Repository permission audit logs
- CI/CD trigger logs
- Reverse proxy / load balancer logs (for API calls)
Detection Rules
Splunk Query
index=github_audit
(event_type="graphql_mutation" OR action="enable_auto_merge")
| eval lower_user=lower(actor)
| lookup repo_permissions repo OUTPUT user, permission
| where permission!="write" AND permission!="admin"
| table _time, actor, repo, action, permission, client_ip, user_agent
Splunk – Unauthorized PR Merge from Fork
index=github_events event_type="pull_request" action="closed"
| where merged="true" AND fork="true"
| lookup repo_permissions repo OUTPUT user, permission
| where permission!="write" AND permission!="admin"
| table _time, repo, actor, permission, source_repo, target_branch
Elastic / Kibana KQL
event.category:"api" AND event.action:"enable_auto_merge" AND
NOT user.permissions:("write" OR "admin")
Elastic – Fork Merge Monitoring
event.action:"pull_request_merged" AND
pull_request.head.repo.fork:true AND
NOT user.permissions:("write" OR "admin")
Microsoft Sentinel (KQL)
GitHubAuditLogs
| where Action == "enable_auto_merge"
| where Permission !in ("write","admin")
| project TimeGenerated, Actor, Repository, Permission, IPAddress
Defensive Recommendations
- Upgrade immediately to a fixed version.
- Enforce branch protection rules on all critical branches.
- Require mandatory reviews before merge.
- Disable auto-merge for repositories that accept external forks unless required.
- Monitor GraphQL mutation activity.
- Review recent merges from forks prior to patch deployment.
- Rotate CI/CD tokens if suspicious merges are discovered.
- Restrict who can enable auto-merge through repository governance policies.
Incident Response Guidance
If exploitation is suspected:
- Identify all merges from forked repositories within the vulnerable window.
- Review diffs for workflow changes, token exfiltration, or suspicious scripts.
- Revert malicious commits.
- Rotate credentials and deployment secrets.
- Preserve audit logs for forensic analysis.
- Validate branch protection enforcement post-patch.
Official Remediation
Upgrade GitHub Enterprise Server to one of the following fixed versions:
- 3.19.2
- 3.18.5
- 3.17.11
Official patch and release notes:
https://docs.github.com/enterprise-server/admin/release-notes
Closing Notes
This vulnerability represented a logic flaw rather than a traditional exploit such as remote code execution. While exploitation required specific repository conditions, the integrity impact could have been significant in environments relying heavily on fork-based contribution models and automated deployment pipelines.
Environments with strict branch protection and enforced review policies were effectively shielded from practical exploitation.
Patch application and audit log review should be treated as high priority in affected deployments.
