
Gitea의 repo migrate 엔드포인트에서 발생하는 인증된 SSRF에 대한 개념 증명 및 실습 환경으로, git이 HTTP 리다이렉트를 따라 루프백 git HTTP로 접근하여 내부 객체를 유출하는 취약점입니다.
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · gitea-git-redir-ssrf
Gitea 1.27.3 - Gitea
IsMigrateURLAllowed는 입력한 URL에 대해 단 한 번 net.LookupIP를 수행합니다. 그런 다음 바이트는 git clone --mirror를 거칩니다. HandleGitCmdHTTPRedirection은 git이 그 홉을 따라가지 못하게 막아야 합니다. 하지만 아무것도 하지 않습니다. 주석 자체가 발견의 핵심입니다. GitLab이 .git 없이 301을 반환하기 때문에 http.followRedirects=false를 빼놓은 것입니다. 풀 미러 fetch도 동일한 no-op을 호출합니다.
로그인한 사용자는 허용 목록에 있는 미끼 호스트에서 마이그레이션할 수 있고, git은 302를 따라 루프백 git HTTP로 들어갑니다. 내부 객체가 그들이 소유한 저장소에 남습니다.
| ID | 아직 CVE 없음 |
| CWE | CWE-918 |
| CVSS | High: 7.7 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N |
| 제품 | Gitea |
| 영향받는 버전 | v1.27.3 (146cc3e)까지 |
| 인증 | 인증됨 (기본 개방형 등록) |
| 라이선스 | GNU Affero GPL v3.0 |
| 랩 | 127.0.0.1 전용 |
등록한 뒤, http://127.0.0.1:.../internal.git으로 302하는 외부처럼 보이는 URL에서 마이그레이션합니다. 루프백으로의 직접 마이그레이션은 거부됩니다. 리다이렉트를 따라간 클론은 거부되지 않습니다. 증거 파일이 그들의 저장소에 남습니다.
file:// 디스크 읽기가 아닙니다. /api/internal에 대한 X-Gitea-Internal-Auth도 아닙니다 (git은 그 헤더를 설정하지 않습니다). 인증되지 않은 RCE도 아닙니다. git이 본문을 저장했다는 것을 별도로 입증하지 않는 한 메타데이터 RCE도 아닙니다.
같은 태그의 잔여물: keys IDOR, hostmatcher 0.0.0.0/8.
v1.27.3은 2026 GHSA 물결을 막았습니다: CVE-2026-60004 (diffpatch 훅 RCE, CISA KEV), CVE-2026-59774 (인증 없는 Org-mode #+INCLUDE), fork-PR Actions 게이트, 리버스 프록시 X-WEBAUTH-USER 기본값. 그것들을 위해 **1.27.3+**에 머무르십시오. 그래도 저는 그 태그를 계속 지켜봤습니다.
CVE-2026-59765는 Go uri.Open을 수정했습니다. CVE-2026-22874는 Go reservedIPNets를 수정했습니다. Git의 리다이렉터는 여전히 FIXME입니다. 체인지로그의 "disable HTTP redirects on pull mirror sync"는 이 함수가 아닙니다.
랩은 Gitea를 8.8.4.2에 두어 8.8.4.10의 미끼 호스트가 hostmatcher에게 외부로 보이게 합니다. 내부 git HTTP는 Gitea netns에서 루프백 전용으로 바인딩됩니다 (network_mode: service:gitea, 포트 9418). 127.0.0.1로의 직접 마이그레이션은 반드시 실패해야 합니다. 리다이렉트를 따라간 클론은 반드시 성공해야 합니다. redir.py는 /bait.git을 http://127.0.0.1:9418/internal.git으로 302합니다. 증거 파일 WITNESS에는 GHSA-GITEA-GIT-REDIR-SSRF가 들어 있습니다.
이미 기록된 잘못된 길: ALLOW_LOCALNETWORKS true (그러면 허용 목록이 사라짐); file://; X-Gitea-Internal-Auth; 리버스 셸. 연극입니다. 직접 루프백 마이그레이션이 거부되는 것이 통제입니다.
클라이언트 버그는 제품 버그처럼 보입니다. http.client를 가리는 헬퍼는 패킷을 전혀 보내지 않습니다. HTTPResponse의 .recv()는 .read()가 아닙니다. 시간을 잡아먹었고 잠시 동안 1.27.3이 일을 끝낸 것처럼 보였기 때문에 한 번 언급합니다.
cd lab
./run.sh
오직 http://127.0.0.1:18103만 대상으로 합니다. ALLOW_LOCALNETWORKS=false.
negative-loopback status=422 You can not import from disallowed hosts
migrate-bait status=201 clone_addr=http://8.8.4.10/bait.git
fetch raw/WITNESS status=200 GHSA-GITEA-GIT-REDIR-SSRF
SUCCESS Gitea #2 git HTTP redirect SSRF
제출 시점의 DNS를 경계로 취급하지 마십시오. http.followRedirects=false를 강제하고 (그리고 GitLab이 여전히 작동하도록 클론 URL을 .git으로 정규화), 또는 모든 홉에서 hostmatcher를 다시 실행하는 다이얼러를 통해 git HTTP를 프록시하십시오.
HandleGitCmdHTTPRedirection · IsMigrateURLAllowedGNU Affero GPL v3.0. LICENSE를 참조하십시오. 루프백 랩 전용. 보증 없음.