Forgejo 16.0.3 이하 쓰고 계신가요? 템플릿 저장소 하나로 서버가 뚫리는 RCE 취약점, 지금 16.0.4로 업데이트하세요

한눈에 보는 핵심 요약
직접 운영하는 Git 호스팅 플랫폼 Forgejo에서 심각한 원격 코드 실행(RCE) 취약점이 발견되어 16.0.4 버전에서 수정되었습니다. 16.0.3 이하 버전을 운영 중이라면 되도록 빨리 업데이트하는 것이 좋습니다.
이번 릴리스의 핵심 내용은 다음과 같습니다.
- 템플릿 저장소를 통한 RCE 차단: 악성 템플릿 저장소 하나로 Forgejo 호스트의 임의 데이터를 읽고, 임의 프로세스를 실행할 수 있었습니다.
- API 토큰 권한 제한 우회 수정: PR의 '유지관리자 수정 허용' 기능이 토큰의 권한 범위를 반영하지 않던 문제를 고쳤습니다.
- 초안 릴리스 첨부파일 노출 수정: 읽기 권한만 있는 사용자, 공개 저장소에서는 비인증 사용자까지 숨겨진 초안 릴리스 첨부파일을 내려받을 수 있었습니다.
- 보안 관련 의존성 업데이트와 함께 권한 처리, 용량 집계, 작업 로그 표시 등 여러 버그도 수정되었습니다.
1. 가장 심각한 문제: 템플릿 저장소를 통한 RCE (PR #14301)
템플릿 저장소 생성 과정
Forgejo에서 템플릿으로 새 저장소를 만들면 내부적으로 다음 순서로 처리됩니다.
- 템플릿 저장소를 복제합니다.
- 복제본에서
.git폴더를 삭제합니다. .forgejo/template에 나열된 파일들의 변수를 치환합니다.- 새 Git 저장소를 초기화합니다.
무엇이 문제였을까?
문제는 3단계 변수 치환에 있었습니다. 공격자가 변수 치환을 악용해 .git 폴더를 다시 만들어 낼 수 있었고, 4단계에서 Git은 새로 초기화하는 대신 이 폴더를 그대로 사용했습니다.
.git 폴더에는 설정 파일, 훅(hook) 등 Git의 동작을 좌우하는 요소가 들어 있습니다. 결국 공격자가 조작한 .git 폴더를 서버가 믿고 쓰게 되면서, Forgejo 호스트의 임의 데이터를 읽거나 임의 프로세스를 실행하는 것까지 가능했습니다.
어떻게 고쳤나?
수정 방식은 단순하지만 효과적입니다. 이제는 변수 치환이 끝난 뒤에도 .git 폴더를 한 번 더 삭제하고 저장소를 초기화합니다. 치환 과정에서 무엇이 만들어지든 초기화 전에 깨끗이 지워집니다.
💡 에디터 코멘트: 사용자가 저장소를 만들 수 있는 공개 인스턴스라면 누구나 악성 템플릿을 올릴 수 있으므로 위험도가 특히 높습니다. 사내용 인스턴스라도 업데이트를 미루지 않는 것이 좋습니다.
2. API 토큰 권한 제한 우회 (PR #14301)
열린 PR에 "allow maintainer edit"(유지관리자 수정 허용) 옵션이 켜져 있으면, 유지관리자는 자신이 소유하지 않은 브랜치에도 커밋할 수 있습니다. Forgejo는 이 기능에 별도의 보안 제어를 사용합니다.
그런데 이 제어가 저장소별 액세스 토큰 등 API 인증의 권한 제한을 반영하지 않았습니다. 그래서 권한을 좁혀 발급한 토큰으로도 허용 범위 밖의 변경을 할 수 있었습니다.
이제는 API에서 수정 가능한 PR인지 확인할 때도 API 인증의 보안 제한을 함께 따집니다.
CI/CD나 봇에 범위를 제한한 토큰을 발급해 두셨다면, 그 제한이 이번 버전부터 제대로 적용됩니다.
3. 초안 릴리스 첨부파일 접근 통제 (PR #13934, 백포트 #14024)
초안(draft) 릴리스는 원래 권한 있는 사람만 봐야 합니다. 하지만 다음과 같은 노출이 있었습니다.
- 저장소 읽기 권한만 있는 사용자가 자신에게는 숨겨진 초안 릴리스 첨부파일의 메타데이터와 전체 내용을 가져올 수 있었습니다.
- 공개 저장소에서는 로그인하지 않은 사용자도 같은 방식으로 접근할 수 있었습니다.
원인은 초안 여부 확인이 일부 경로에서 빠져 있었기 때문입니다.
| 경로 | 초안 여부 확인 |
|---|---|
| GetRelease | ✅ 확인함 |
| ListReleaseAttachments | ✅ 확인함 |
| GetReleaseAttachment (API) | ❌ 누락 |
| ServeAttachment (웹 다운로드) | ❌ 누락 |
이는 Forgejo가 갈라져 나온 Gitea에서 CVE-2026-27660 / GHSA-q9pg-jj6x-j9p6으로 수정된 것과 같은 유형의 문제입니다. 뿌리가 같은 프로젝트끼리 비슷한 취약점이 함께 발견되는 경우가 많다는 점을 보여 줍니다.
4. 보안 관련 의존성 업데이트
google.golang.org/grpc→ v1.83.1golang.org/x/crypto→ v0.56.0
그 밖에 사용자에게 영향을 주는 수정 사항
🔐 저장소 접근 권한 처리
access테이블 재계산 로직을 한곳으로 모으고, 제한된 사용자(restricted user)의 권한 불일치를 수정했습니다. (PR #14243, 백포트 #14255)- 조직 팀이
admin으로 설정되었을 때 관련 저장소에owner권한이 부여되던 문제를 해결했습니다. (PR #14032, 백포트 #14034)
📦 용량 집계 · 작업 로그 · Git 리소스 정리
- 패키지 블롭이 할당량(quota)에 중복 집계되지 않도록 바꿨습니다. (PR #14221, 백포트 #14296)
- 작업(Actions) 로그가 있으면 화면에 제대로 표시되도록 수정했습니다. (PR #14263, 백포트 #14285)
- Git 저장소를 제대로 닫지 않던 코드 경로를 수정했습니다.
git cat-file --batch[-check]프로세스 누수와 관련이 있었을 수 있습니다. (PR #14080, 백포트 #14089)
🎨 화면 표시와 번역
- 커밋 기반 리뷰의 해시 박스 디자인 수정 (PR #14116, 백포트 #14118)
- 조직 프로젝트 헤더에 제목과 조직 이름 표시 (PR #13586, 백포트 #14065)
- MS Teams 웹훅 카드에 줄바꿈 적용 (PR #14058, 백포트 #14115)
- Codeberg Translate 번역 갱신 및 헝가리어 수정 (PR #14311, 원본 #13953)
운영자를 위한 체크리스트 ✅
- 현재 버전 확인: 16.0.3 이하라면 영향을 받습니다.
- 16.0.4로 즉시 업데이트: 특히 외부 사용자가 저장소를 만들 수 있는 공개 인스턴스라면 최우선으로 진행하세요.
- 템플릿 저장소 점검: 업데이트 전까지 출처가 불분명한 템플릿 저장소 사용을 피하고, 기존 템플릿의
.forgejo/template구성에 수상한 부분이 없는지 살펴보세요. - 토큰 권한 재검토: 권한을 제한해 발급한 API 토큰이 의도한 범위에서만 동작하는지 확인하세요.
- 초안 릴리스 확인: 초안 릴리스 첨부파일에 민감한 파일이 있었다면 노출 가능성을 염두에 두고 대응하세요.
마치며
이번 취약점은 '삭제했으니 안전하다'는 가정이 이후 단계에서 깨질 수 있다는 점을 잘 보여 줍니다. 파일을 지운 뒤 사용자 입력으로 다시 파일을 만드는 흐름이 있다면, 마지막 신뢰 지점 직전에 한 번 더 검증해야 합니다. 셀프 호스팅 Git 서비스를 운영 중이라면 이번 기회에 업데이트 주기와 보안 공지 구독 여부도 함께 점검해 보세요.