The vulnerability allows an authenticated user with only read access to a repository to gain write access by exploiting the "Allow edits from maintainers" feature in pull requests. The core of the issue lies in the CanMaintainerWriteToBranch function, which is called during a git push to a branch that is the head of a pull request.
The exploitation process is as follows:
- The attacker forks a target repository.
- The attacker creates a "reverse" pull request, where the
BASE branch is on their own fork, and the HEAD branch is on the upstream target repository.
- The attacker enables the "Allow edits from maintainers" option on this pull request. The system at the time of PR creation did not validate if the user had the right to enable this on the
HEAD repository.
- The attacker then pushes a malicious commit to the
HEAD branch in the upstream repository.
- Gitea's
pre-receive hook triggers a permission check, which calls the vulnerable CanMaintainerWriteToBranch function.
- The vulnerable version of this function would check if the pusher (the attacker) has write permission on the
BASE repository of the pull request. Since the BASE is the attacker's own fork, this check passes.
- The push is accepted, and the attacker successfully writes to the target repository.
The patch addresses this by modifying CanMaintainerWriteToBranch. The new version adds a critical check to ensure that the original creator of the pull request had write permissions to the HEAD repository. If they did not, "maintainer edits" are disallowed, regardless of the flag's value, thus preventing the unauthorized push.