Skip to content

Gitea: Authorization Bypass via "Allow edits from maintainers" allows unauthorized commits to any readable repo

High severity GitHub Reviewed Published Jun 5, 2026 in go-gitea/gitea • Updated Jun 16, 2026

Package

gomod code.gitea.io/gitea (Go)

Affected versions

<= 1.26.1

Patched versions

1.26.2

Description

Summary

Any authenticated low-privilege user with read access to a repository can push arbitrary commits directly to that repository, bypassing all write-access checks.

Vulnerability

Gitea's "Allow edits from maintainers" PR option can be abused via reverse-fork PRs:

  1. The web UI PR-create endpoint binds allow_maintainer_edit=true without verifying that the submitter has write access to the HEAD repository.
  2. Gitea allows creating a PR where BASE = attacker's fork and HEAD = upstream target. The attacker is "maintainer" of the BASE (their own fork), so the flag is set against the upstream HEAD.
  3. On git push over HTTP/SSH, Gitea relaxes the required access mode to Read when SupportProcReceive is enabled (routers/web/repo/githttp.go, routers/private/serv.go) and defers enforcement to the pre-receive hook.
  4. The pre-receive hook calls CanMaintainerWriteToBranch (models/issues/pull_list.go), which finds the malicious PR, sees AllowMaintainerEdit=true, and checks whether the pusher has write access to the BASE repo. Since BASE is the attacker's own fork, the check passes and the push is authorized against the upstream.

Exploitation

  1. Attacker forks the target repository.
  2. Attacker visits the web compare endpoint and creates a PR with BASE = their_fork, HEAD = upstream, and "Allow edits from maintainers" checked.
  3. Attacker clones their fork, makes a commit, and runs git push <upstream_url> <branch> — the push is accepted.

Reproduction

python3 poc.py --repo http://gitea:3000/victim/repo --user attacker --password attacker_pass

poc.py

Expected output:

[+] target: victim/my_repo  default branch: main
[*] forking -> attacker/my_repo_pocfork (202)
[+] fork ready
[+] malicious PR created (BASE=attacker fork, HEAD=upstream)

remote: . Processing 1 references
remote: Processed 1 references in total
To http://192.168.101.20:3000/victim/my_repo.git
   e5c07b3..9a0b884  main -> main

[+] latest commit on victim/my_repo@main: 'PoC: unauthorized commit via maintainer-edit bypass'
[+] CONFIRMED: unauthorized push to upstream succeeded.

A PWNED.txt file will appear on the target repo's default branch, committed by the attacker who has no write access.

Impact

Full repository compromise. Any logged-in user can backdoor any repository they can read, including all public repositories on the instance.

Suggested Fix

Two independent checks are missing; both should be added for defense in depth:

  1. At PR creation: before setting AllowMaintainerEdit = true, verify the submitter has write access to the HEAD repository.
  2. In CanMaintainerWriteToBranch: verify that the PR's HEAD repo matches the repository being pushed to, and that the PR was opened by a legitimate owner/writer of the HEAD repository. Do not trust AllowMaintainerEdit solely based on BASE write access.

References

@lunny lunny published to go-gitea/gitea Jun 5, 2026
Published to the GitHub Advisory Database Jun 16, 2026
Reviewed Jun 16, 2026
Last updated Jun 16, 2026

Severity

High

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
Low
User interaction
None
Scope
Changed
Confidentiality
Low
Integrity
High
Availability
None

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:H/A:N

EPSS score

Exploit Prediction Scoring System (EPSS)

This score estimates the probability of this vulnerability being exploited within the next 30 days. Data provided by FIRST.
(9th percentile)

Weaknesses

Incorrect Authorization

The product performs an authorization check when an actor attempts to access a resource or perform an action, but it does not correctly perform the check. Learn more on MITRE.

CVE ID

CVE-2026-26231

GHSA ID

GHSA-mm7c-rhg6-qr4r

Source code

Credits

Loading Checking history
See something to contribute? Suggest improvements for this vulnerability.