flawopen.com/Incidents/gitlab-commits-api-path-traversal-september-2026
CVE-2026-85706: pengungkapan berkas server GitLab
Parser unggahan GitLab memilih berkas server tanpa autentikasi; escape keliru menampilkan cuplikan di galat, tetapi pemilihan tak membocorkan isinya.[1], [3]
Bayangkan petugas penerimaan mengikuti lokasi lemari yang ditulis pengunjung, bukan dokumen di baki masuk. Sebelum memeriksa kartu identitas, ia membuka lemari itu; bila satu baris sulit dibaca, ia membacakannya dalam pesan galat. Membuka dokumen adalah satu kesalahan, membacakan isinya adalah kesalahan lain.[1]
Konsep Kunci & Istilah
Upload metadata- file.path atau metadata.path dari permintaan tidak boleh menggantikan penyangga yang didaftarkan oleh pemroses unggahan tepercaya.[1]
Percent decoding- Dalam penguraian formulir, % diikuti dua digit heksadesimal akan didekode; urutan tidak valid dapat memunculkan galat yang memuat potongan bermasalah.[1]
CWE-22 / CVSS- CNA menggolongkan
CVE-2026-85706sebagai penelusuran lintas jalur, CVSS 10.0 Kritis. Batas yang dilanggar ialah pemilihan berkas server oleh peminta.[3]
Pemetaan kerangka kerja
- Referensi CWE untuk kelemahan yang dijelaskan dalam panduan ini: CWE-22
- CISA KEV — ditambahkan 2026-09-11 — CVE-2026-85706
Kronologi Insiden
GitLab merilis perbaikan 19.1.8, 19.2.6, dan 19.3.2.[2]
Pengumuman diperbarui untuk mencakup perbaikan pada 18.11.12 dan 19.0.9.[2]
Alur Serangan Langkah demi Langkah
Pemilihan sebelum autentikasi
Metadata unggahan dapat menggantikan penyangga sementara yang diharapkan dengan jalur server sebelum autentikasi.[1]
Isi menjadi parameter
Dengan application/x-www-form-urlencoded, berkas terpilih ditafsirkan sebagai data formulir, bukan dikirim sebagai jawaban commit biasa.[1]
Pantulan dalam galat
Escape persen yang tidak valid dapat memasukkan potongan yang gagal ke galat. Pemisah & dan = menentukan cakupannya; pembacaan saja tidak membuktikan kebocoran.[1]
Penyelidikan
Cocokkan entri Rails API dan Workhorse melalui correlation_id; bandingkan api_error dengan written_bytes untuk menilai apakah byte terkirim dalam respons.[1]
Kode Sumber: Rentan vs Aman
Model Python untuk belajar, bukan sumber atau tambalan GitLab. Contoh rentan hanya memakai penyangga di memori dan menganggap setiap % sebagai galat; validasi nyata dan pemilihan potongan tidak ditiru. Model yang diperkuat mengautentikasi lebih dulu, menolak metadata jalur, menerima hanya byte dari sistem unggahan tepercaya, membatasi ukuran, dan mengembalikan galat umum. Pasang pembaruan vendor: autentikasi di rute terlambat jika lapisan sebelumnya sudah membaca berkas.[1]
from urllib.parse import unquote_to_bytes
def parse_upload(authenticated, metadata, buffers):
# Aman di memori; tidak mengakses sistem berkas.
body = buffers.get(metadata.get("path"), b"")
if b"%" in body:
return 400, body.decode("ascii", errors="replace")
if not authenticated:
return 401, "Unauthorized"
return 200, unquote_to_bytes(body)
from urllib.parse import unquote_to_bytes
MAX_BYTES = 4096
HEX = frozenset(b"0123456789abcdefABCDEF")
def parse_upload(authenticated, metadata, registered_body):
# registered_body berasal dari middleware unggahan tepercaya,
# bukan dari jalur yang dipilih melalui parameter permintaan.
if not authenticated:
return 401, "Unauthorized"
if metadata or type(registered_body) is not bytes:
return 400, "Invalid upload"
if len(registered_body) > MAX_BYTES:
return 413, "Upload too large"
for i, byte in enumerate(registered_body):
if byte == 37 and (i + 2 >= len(registered_body) or
registered_body[i+1] not in HEX or
registered_body[i+2] not in HEX):
return 400, "Invalid upload"
return 200, unquote_to_bytes(registered_body)
Daftar Periksa Penguatan Sistem Rekayasa
- ✓Perbarui ke versi perbaikan yang didukung. Batas minimum tiap cabang ialah 18.11.12, 19.0.9, 19.1.8, 19.2.6, dan 19.3.2; versi terdampak mulai 18.7. Cocokkan versi terpasang dengan pengumuman vendor.[2], [3]
- ✓Uji permintaan anonim memakai penanda tidak berbahaya di memori: tidak ada pencarian penyangga sebelum autentikasi dan tidak ada penanda pada respons atau log biasa. Tolak metadata jalur sebelum penguraian.[1]
- ✓Simpan log Rails API dan Workhorse; cocokkan entri melalui
correlation_id, lalu bandingkanapi_errordenganwritten_bytes. Periksa nilai file.path dan metadata.path yang telah didekode alih-alih membuang seluruh baris karena ada jalur unggahan yang wajar. File yang dibaca belum tentu diungkapkan: menurut GitLab, fragmen yang tercermin di api_error dan dikonfirmasi oleh written_bytes dari Workhorse menunjukkan byte yang dikirim; status HTTP saja tidak cukup untuk menyimpulkan.[1] - ✓Batasi rotasi pada kredensial yang termasuk dalam paparan terkonfirmasi atau yang patut diduga. Jika
db_key_baseatauotp_key_basemungkin terdampak, konsultasikan dengan dukungan GitLab sebelum merotasinya: GitLab menyatakan saat ini tidak ada jalur rotasi yang didukung untukdb_key_basedan memperingatkan bahwa rotasi kunci yang tidak didukung dapat menyebabkan kehilangan data. Tidak adanya log bukan bukti bahwa tidak terjadi paparan.[1]