보안
GitLab의 만점 10.0은 막혔다. 읽혀 나간 비밀은 그대로다
CVE-2026-85706은 인증 없이도 자체 관리형 GitLab 서버의 임의 파일을 읽을 수 있게 했고, CISA는 패치가 나온 다음 날 이를 실제 악용 목록에 올렸다. 업그레이드는 읽기를 멈추지만, 이미 빠져나간 자격 증명에 대해서는 아무것도 해주지 않는다.
MAI
GitLab은 9월 10일, 저장소 commits API에 존재하는 경로 조작(path traversal) 취약점 CVE-2026-85706을 해결하는 긴급 패치 릴리스를 배포했다. CVSS 점수는 10.0이다. CISA는 그 다음 날 실제 악용 정황이 있다며 이 취약점을 알려진 악용 취약점(KEV) 목록에 추가하고, 연방 민간기관에 3일이라는 조치 기한을 부여했다. 이 기관이 내리는 기한 중 가장 짧은 축에 속한다. 그 기한은 이미 지났다. 보안 업체 watchTowr은 9월 11일부터 실제 환경에서의 탐색 시도를 관측했다고 보고했다.
개별 날짜보다 중요한 것은 그 순서다. 벤더의 패치와, 공격자가 이미 사용하고 있는 결함만 등재되는 정부 목록 사이의 간격이 단 하루였다. 자체 인프라에서 GitLab을 운영하는 조직에게 수정이 공개된 시점과 실제로 적용한 시점 사이의 공백은, 그 서버가 요청하는 누구에게나 읽혔던 시간 그 자체다.
무엇이 문제인가
GitLab의 권고문은 이 문제를 이렇게 설명한다.
GitLab은 특정 조건에서 저장소 commits API의 부적절한 경로 제한과 인증 강제 누락으로 인해 인증되지 않은 사용자가 GitLab 서버의 임의 파일을 읽을 수 있었던 문제를 해결했습니다.
CVSS 벡터는 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N이다. 네트워크를 통해 도달 가능하고, 공격 복잡도는 낮으며, 권한도 사용자 상호작용도 필요 없다. 그리고 점수를 만점으로 끌어올린 요소가 범위 변경(Scope: Changed)이다. 범위 변경이란 피해 반경이 취약한 소프트웨어 안에서 멈추지 않는다는 뜻을, 점수 체계가 나름의 방식으로 표현한 것이다. 이번 사안에서 그것은 정확한 판단이며, 이 글의 나머지는 그 이유에 대한 논증이다.
이 문제는 GitLab의 HackerOne 프로그램을 통해 보고됐고, 연구자는 s3ntago로 기재돼 있다. GitLab.com과 GitLab Dedicated는 이미 패치된 코드로 운영되고 있으므로, 이것은 전적으로 자체 관리형 환경의 문제다.
| 영향을 받는 버전 | 수정 버전 |
|---|---|
| 18.7부터 19.1.7까지 | 19.1.8 |
| 19.2.0부터 19.2.5까지 | 19.2.6 |
| 19.3.0부터 19.3.1까지 | 19.3.2 |
같은 릴리스는 또 하나의 치명적 결함인 CVE-2026-87719(Enterprise Edition의 GraphQL 역직렬화 취약점)와 높음 등급 버그 6건도 함께 수정한다. 파일 읽기 문제 때문에 업그레이드하는 조직은 이것들도 같이 얻게 되며, 이는 나머지를 그대로 남겨두는 우회책을 찾기보다 업그레이드를 택해야 할 근거가 된다.
소스 관리 서버에서의 파일 읽기는 단순한 파일 읽기가 아니다
임의 파일 읽기는 보통 원격 코드 실행보다 한 단계 아래로 분류되고, 대부분의 맥락에서 그 분류는 타당하다. 그러나 자체 관리형 GitLab 인스턴스는 '대부분의 맥락'이 아니다. 그것은 조직이 의도적으로, 하위의 모든 시스템에 닿는 자격 증명의 보관자로 삼은 장비다. CI/CD 변수, 배포 토큰, 러너 등록 토큰, 컨테이너 레지스트리 자격 증명, 클라우드 제공자 키, 서명 자료, 그리고 이것들을 엮는 설정까지. 통합 DevSecOps 플랫폼의 가치 제안 자체가, 파이프라인이 접근할 수 있도록 그 비밀들을 한곳에 모아두는 데 있다.
따라서 그 호스트에 대한 읽기 권한은 서버 한 대에 대한 읽기 권한이 아니다. 그 서버가 배포하는 자산 전체의 열쇠에 대한 읽기 권한이다. GitLab 장비 위에서 코드 한 줄 실행하지 않은 공격자라도 그 장비의 자격으로 다른 모든 시스템에 인증할 수 있고, 그 이후의 모든 행위는 파이프라인이 제 일을 하는 것처럼만 보인다. 이것이 실무에서 '범위 변경'이 의미하는 바이며, 이 사안을 정보 노출 버그가 아니라 디렉터리 서비스 침해와 같은 범주로 봐야 하는 이유다.
패치는 문을 닫는다. 열쇠를 회수하지는 않는다
여기가 조직이 미루는 지점이고, 패치가 나온 지 며칠이 지난 지금 이 이야기를 쓰는 이유다.
19.3.2, 19.2.6, 19.1.8로의 업그레이드는 읽기를 멈춘다. 이미 읽힌 것에 대해서는 아무것도 하지 않는다. 업그레이드 이전에 노출된 인스턴스에 보관돼 있던 비밀은 유출된 것으로 간주하고 교체해야 한다. 그리고 성숙한 GitLab 환경에서의 자격 증명 교체는 길고 지루하며 부서를 넘나드는 작업이다. 토큰이 바뀌면 요란하게 깨질 파이프라인들을 하나하나 건드려야 하기 때문이다. 정확히 '다음 분기에 하자'로 잡혔다가 결국 하지 않게 되는 종류의 일이다.
Rapid7은 이 점을 분명히 하며, 업데이트를 적용한 뒤에도 침해 흔적을 찾아볼 것을 권고하고, CISA의 BOD 26-04에 따라 KEV 등재에 수반되는 포렌식 분류 의무를 가리킨다. 연방기관은 그 작업을 의무적으로 해야 한다. 나머지 조직은 그저 같은 공격자에게 노출돼 있을 뿐이다.
업그레이드를 계획하기 전에 알아둘 운영상의 사항이 두 가지 있다. 패치에는 데이터베이스 마이그레이션이 포함되므로 단일 노드 설치 환경에서는 다운타임이 발생한다. 겪고 나서 알기보다 미리 계획에 넣는 편이 낫다. 또 하나, 자격 증명 교체가 필요한지 판단할 때 기준으로 삼아야 할 숫자는 패치와 KEV 등재 사이의 '하루'다. 인터넷에 노출된 인스턴스가 9월 10일 이후 어느 시점에라도 패치되지 않은 상태였다면, 도달당했다고 가정해야 한다.
더 큰 논점
CISA는 경로 조작을 악성 사이버 행위자들이 자주 쓰는 공격 벡터라고 설명한다. 이는 이 부류의 버그가 30년 가까이 충분히 이해돼 왔음에도 사람들이 운영하는 가장 민감한 소프트웨어에 계속 나타난다는 사실을 관료적으로 바꿔 말한 것이다. 흥미로운 질문은 경로 제한 검사가 어쩌다 빠졌는가가 아니다. 어째서 이토록 많은 조직이 보유한 모든 자격 증명을 인터넷에 면한 단일 웹 애플리케이션 뒤에 몰아넣고도, 그 애플리케이션이 뚫렸을 때 그것들을 교체할 절차를 한 번도 연습해두지 않았는가다.
패치는 나와 있고 수정 자체는 간단하다. 문제는 패치 이후에 날아오는 청구서이고, 그것은 끝내 지불되지 않을 것이다. 둘 중 큰 쪽은 후자다.
Sources: GitLab Critical Patch Release: 19.3.2, 19.2.6, 19.1.8 · Rapid7: CVE-2026-85706 Critical GitLab Path Traversal Exploited in the Wild · BleepingComputer: CISA — hackers now exploit max severity GitLab flaw in attacks · The Register: Perfect-10 GitLab bug under attack days after patch lands · Infosecurity Magazine: Hackers Exploit Maximum Severity Flaw in GitLab · CISA Known Exploited Vulnerabilities Catalog