
GitLab CVE-2026-97229(및 CVE-2026-110264)에 대한 탐지 전용 트리아지: 자체 관리형 GitLab 버전과 해당 Ruby 버전을 평가하여 10월 12일 패치 및 사용자 정의 Ruby 함정을 포착합니다. 페이로드 없음, 네트워크 프로브 없음.
gitlab-onigmo-scanner두 가지 CVSS 10.0 GitLab 정규식 취약점인 CVE-2026-97229와 CVE-2026-110264에 대한 버전 분류 도구입니다. 소유한 GitLab 버전을 입력하면 해당 빌드가 여전히 취약한지 알려주며, 이미 사람들을 당황하게 만든 두 가지 함정을 잡아냅니다. 네트워크에 접속하지 않고, 페이로드를 전송하지 않으며, CI 린트 엔드포인트를 호출하지 않고, 조작된 정규식을 컴파일하지도 않습니다.
취약점세부 정보 | 값 |
|---|---|
CVE | CVE-2026-97229, 그리고 이와 함께 등급이 매겨진 CVE-2026-110264 |
버그 | GitLab이 사용자 제공 정규식을 컴파일할 때 Ruby에 내장된 정규식 엔진인 Onigmo의 정수 오버플로(CWE-190) |
영향 | 특정 조건에서 자체 관리형 GitLab 서버의 인증 불필요 원격 코드 실행 |
심각도 | 둘 다 10.0 치명적, GitLab이 CNA로서 산정 |
악용 | CVE-2026-97229는 2026-10-29에 CISA KEV에 추가되었으며, 연방 기한은 2026-11-01. CVE-2026-110264는 이 글 작성 시점 기준 KEV 목록에 없으며, GitLab은 공격에 사용된 정황이 없다고 보고함 |
CVE-2026-97229는 CI/CD 정규식 취약점입니다. CI/CD 구성에 특수하게 조작된 정규식이 포함될 경우 발생하며, 정규식 검증이 불충분했고, 2026-10-12에 수정되었습니다. CVE-2026-110264는 2026-10-21에 수정된 두 번째이자 더 광범위한 정규식 취약점으로, 7.0까지 거슬러 올라가는 모든 자체 관리형 릴리스에 영향을 미칩니다. 동일한 엔진, 동일한 점수, 다른 버그이며, 바로 이것이 하나의 점검으로 충분하지 않은 이유입니다.
수정된 버전CVE-2026-97229 (2026-10-12 수정)라인 | 수정 버전 |
|---|---|
GitLab 19.2 | 19.2.8 |
GitLab 19.3 | 19.3.5 |
GitLab 19.4 | 19.4.2 |
GitLab 19.5, 19.2보다 오래된 버전 | 이 CVE의 영향을 받는 것으로 나열되지 않음 |
CVE-2026-110264 (2026-10-21 수정)라인 | 수정 버전 |
|---|---|
GitLab 19.5 | 19.5.1 |
GitLab 19.4 | 19.4.3 |
GitLab 19.3 | 19.3.6 |
GitLab 19.2 | 19.2.9 |
GitLab 19.1 | 19.1.9 |
GitLab 19.0 | 19.0.10 |
GitLab 18.11 | 18.11.13 |
GitLab 18.10 및 이전 버전 | 수정 릴리스 없음, 18.11.13 이상으로 업그레이드 |
Ruby, 소스 및 사용자 정의 이미지 설치의 경우라인 | 수정 버전 |
|---|---|
Ruby 3.3 | 3.3.13 |
Ruby 3.4 | 3.4.12 |
Ruby 4.0 | 4.0.9 |
Ruby 3.2 및 이전 버전 | 수정 없음, 지원 종료, 3.4 또는 4.0으로 이동 |
함정 1: 10월 12일 패치가 10월 21일을 커버하지 않음19.4.2, 19.3.5, 19.2.8은 CVE-2026-97229를 수정했습니다. 이들 모두는 각 브랜치의 CVE-2026-110264 수정 버전(19.4.3, 19.3.6, 19.2.9)보다 낮습니다. 10월 12일에 패치하고 멈췄다면 여전히 취약하며, 첫 번째 CVE만 아는 스캐너는 당신을 안전하다고 판정할 것입니다. 이 도구는 둘 다를 평가하며, 해당 함정을 발견하면 출력에서 이를 명시합니다.
함정 2: GitLab 업그레이드가 자체 Ruby를 수정하지 않음GitLab의 수정은 공식 패키지와 이미지에 번들로 포함된 Ruby에 대한 패치입니다. 소스 설치나 Ruby를 별도로 설치하는 사용자 정의 이미지는 GitLab 업그레이드로부터 해당 패치를 받지 못합니다. Alpine Linux가 바로 이 상황을 겪었습니다. 2026-10-22에 GitLab 19.3.6으로 업그레이드했지만 여전히 취약했는데, 해당 이미지가 표준 Ruby를 사용했기 때문입니다. 공격자는 2026-10-20과 21에 서버를 탐색했고, 워커를 여덟 번 충돌시켰으며, 그중 네 번은 익스플로잇을 부분적으로 진행했고, 25일과 26일에 다시 돌아왔습니다. Alpine은 익스플로잇이 성공했다는 증거를 찾지 못했지만, 이를 배제할 수도 없었기에 인스턴스를 처음부터 재구축하고, 비밀 키를 교체하고, 모든 비밀번호를 재설정했습니다. 2026-10-27 이후 다시 받아온 수정된 이미지는 Ruby 3.3.13을 포함합니다.
따라서 --install-type official은 GitLab 버전만 등급을 매기는데, Ruby가 함께 따라오기 때문입니다. --install-type source 또는 custom은 --ruby-version으로 제공한 Ruby도 함께 등급을 매기며, Ruby 버전이 없으면 깨끗한 것이 아니라 UNKNOWN으로 등급이 매겨집니다. Ruby 4.0.8은 알아둘 가치가 있는 특별한 경우입니다. 이 버전은 CVE-2026-97229 버그는 수정하지만 CVE-2026-110264는 수정하지 않으므로, 여기서는 VULNERABLE로 등급이 매겨집니다. Ruby는 이러한 수정에 대해 자체적으로 요청한 CVE 식별자가 없으며, 이것이 CVE 기록을 설치된 패키지와 대조하는 스캐너가 어디에서도 취약한 Ruby를 찾지 못하는 이유입니다. 이 도구는 대신 Ruby 버전을 직접 확인합니다.
확인하는 항목GitLab 버전: CVE-2026-97229와 CVE-2026-110264를 각각 확인한 뒤 하나의 종합 판정CSV 인벤토리: name,gitlab_version,ruby_version,install_type,hostingsource 또는 custom이라고 지정한 경우의 Ruby 함정GitLab.com 및 Dedicated는 조치 불필요각 발견 사항에는 판정이 부여됩니다: VULNERABLE, FIXED, EOL_NO_FIX, UNKNOWN, 또는 해당 브랜치에 영향을 주지 않는 단일 CVE에 대한 NOT_AFFECTED. EOL_NO_FIX는 취약한 것으로 간주됩니다. 해당 라인에는 패치가 제공되지 않기 때문입니다.
절대 하지 않는 일네트워크 요청 없음. 원격 서버 프로빙 없음. 조작된 정규식 없음, CI 린트 요청 없음, 익스플로잇 트래픽 없음, PoC 코드 없음. 제공한 버전 문자열을 읽고 멈춥니다. 이는 의도된 것입니다. CVE-2026-97229에 대한 공개 PoC는 이미 존재하며, 여기서 이를 재현하는 것은 방어적으로 아무것도 추가하지 않습니다.
PoC와 버전 카운터가 이미 존재하는데 왜 이것인가CVE-2026-97229에 대한 공개 자료는 대부분 공격적입니다: git 사용자로 코드를 실행하는 PoC와 어떤 빌드가 무기화 가능한지 매핑하는 랩이 있습니다. Censys는 버전별로 노출된 호스트를 집계합니다. GitLab은 로그에서 익스플로잇 시도를 탐지하기 위한 Sigma 규칙을 게시했습니다. 그중 어느 것도 10월의 두 CVSS 10.0 결함을 함께 등급 매기고 source 또는 custom 설치 아래의 Ruby를 확인하는 독립형 방어 트리아지 도구가 아닙니다. 그 공백이 바로 이 저장소입니다: 하나의 명령, 두 CVE, 두 함정, 페이로드 없음. GitLab의 Sigma 규칙 대신이 아니라 함께 사용하십시오. 인스턴스가 프로빙되었다면 버전 트리아지는 침해 트리아지가 아닙니다: 워커 크래시 로그와 Onigmo 크래시 보고서를 확인하고, 시도를 배제할 수 없다면 Alpine의 사례를 따르십시오.
등급 매기기발견 사항 | 심각도 |
|---|---|
GitLab이 두 CVE 중 하나에 대해 해당 브랜치의 수정 버전 미만 | VULNERABLE |
GitLab이 18.10 이하, 또는 source/custom 설치에서 Ruby 3.2 이하 | EOL_NO_FIX, 취약한 것으로 간주 |
GitLab이 두 수정 버전 모두 이상이고, 해당되는 경우 수정된 Ruby | FIXED |
Ruby 버전이 없는 Source/custom 설치, 또는 이 도구의 데이터(2026-10-30)보다 새로운 브랜치 | UNKNOWN, 깨끗하지 않음 |
GitLab.com / Dedicated | FIXED, GitLab에 의해 패치됨 |
사용법# One instance, official package or image
python3 gitlab_onigmo_scanner.py --version 19.4.2
# One instance, source install with its own Ruby
python3 gitlab_onigmo_scanner.py --version 19.4.3 --ruby-version 3.4.11 --install-type source
# A whole estate, machine-readable output
python3 gitlab_onigmo_scanner.py --list inventory.csv --json
# Tests (version tables only, no network)
python3 -m unittest discover -s tests -v
inventory.csv 형식, 헤더 행은 선택 사항:
| Column | Description |
|---|---|
host | Hostname or IP address |
port | SSH port (default: 22) |
user | SSH username |
password | SSH password (optional if using key auth) |
key | Path to SSH private key (optional) |
passphrase | Key passphrase (optional) |
sudo | true/false — enable sudo for privileged commands |
sudo_password | Sudo password (optional) |
tags | Comma-separated tags for filtering |
Example:
host,port,user,password,key,passphrase,sudo,sudo_password,tags
192.168.1.10,22,ubuntu,,/home/user/.ssh/id_rsa,,true,secret,web,prod
192.168.1.11,2222,admin,adminpass,,,false,,db,staging
--inventory-formatcsv (default)json — array of objects with the same keys as the CSV columns--inventory-tagsFilter hosts by tag (comma-separated, OR logic):
./linux-sudo-checker --inventory inventory.csv --inventory-tags web,prod
--inventory-concurrencyNumber of hosts to process in parallel (default: 5).
--inventory-timeoutPer-host connection timeout in seconds (default: 10).
--inventory-outputWrite per-host results to a directory (one JSON file per host):
./linux-sudo-checker --inventory inventory.csv --inventory-output ./results/
Human-readable report with color-coded severity levels.
./linux-sudo-checker --json
{
"timestamp": "2024-01-15T10:30:00Z",
"hostname": "web01",
"findings": [
{
"id": "SUDO-001",
"severity": "high",
"title": "NOPASSWD entry for ALL commands",
"description": "User 'deploy' can run any command as root without a password.",
"evidence": "deploy ALL=(ALL) NOPASSWD: ALL",
"remediation": "Restrict the sudoers entry to specific commands."
}
]
}
./linux-sudo-checker --sarif --output report.sarif
Compatible with GitHub Code Scanning, Azure DevOps, and other SARIF-consuming tools.
./linux-sudo-checker --html --output report.html
Self-contained HTML report with embedded CSS and JavaScript.