FlawOpen

flawopen.com/Teardowns/cve-2026-102437-deepseek-reasonix-git-filter-command-injection

● CVE-2026-102437 · CVSS 7.8[2] · Tinggi
Riset Keamanan · FlawOpen

CVE-2026-102437: injeksi Git saat lihat diff di Reasonix

Pasangan .gitattributes/.git/config dapat menjalankan filter clean saat Reasonix membuka diff. Perbarui npm ke 1.39.3 atau Studio 2.21.0.[1], [2], [3], [6], [7]

💡 Penjelasan Sederhana (ELI5)

Bayangkan meja penyortiran yang berjanji hanya membandingkan dua label. Sebuah paket dapat membawa catatan rute yang meminta meja menjalankan alat bantu terdaftar sebelum membandingkan isinya. Reasonix menonaktifkan beberapa alat bantu Git, tetapi filter clean per berkas adalah jalur yang berbeda. Saat panel diff meminta Git menyiapkan berkas untuk dibandingkan, filter ini dapat berjalan dengan hak akses pengembang.[1], [3]

Konsep Kunci & Istilah

Filter clean Git
Transformasi terkonfigurasi yang dapat dijalankan Git untuk mengubah isi berkas di working tree ke bentuk yang disimpan dalam repositori.[1], [3]
.gitattributes
Berkas yang dilacak repositori dan dapat menetapkan filter bernama untuk jalur tertentu.[1]
.git/config
Konfigurasi Git lokal repositori yang dapat menentukan perintah untuk filter bernama. Clone biasa tidak menyalin berkas lokal ini.[1], [3]
Penampil diff
Fitur yang meminta Git menyiapkan dan membandingkan isi working tree suatu berkas dengan isi yang telah dikomit.[1]

Pemetaan kerangka kerja

  • Referensi CWE untuk kelemahan yang dijelaskan dalam panduan ini: CWE-78

Analisis Akar Masalah (Root Cause)

Reasonix memperkuat pemanggilan git diff dengan --no-ext-diff dan --no-textconv , tetapi opsi tersebut mengatur mekanisme diff eksternal dan konversi teks; keduanya tidak menonaktifkan filter konten clean Git. Tampilan perubahan workspace memanggil git diff untuk jalur yang dipilih. Jika konten repositori menetapkan filter untuk jalur tersebut melalui .gitattributes dan konfigurasi Git lokal mendefinisikan perintah drivernya, Git dapat menjalankan perintah itu saat membuat blob pembanding. CVE ini menjelaskan penyerang lokal dan mensyaratkan pengguna membuka diff. Pengungkapan GitLab menyatakan clone biasa tidak membawa .git/config ; arsip, direktori tersinkron, cache, atau devcontainer yang telah disiapkan dapat menyertakannya. Pengungkapan itu juga menjelaskan agen lokal dengan hak yang sama yang dapat menulis konfigurasi lokal ke repositori. Dampaknya adalah eksekusi perintah lokal dengan hak pengguna Reasonix, bukan eksekusi kode jarak jauh hanya karena membuka repositori yang di-host di GitLab.[1], [3]

Alur Serangan Langkah demi Langkah

Langkah 1

Workspace menerima keadaan repositori yang tidak tepercaya

Pengembang membuka proyek yang atribut terlacaknya menetapkan filter untuk sebuah berkas dan konfigurasi Git lokalnya mendefinisikan filter tersebut. Pemberitahuan maintainer mensyaratkan kedua bagian; clone biasa saja tidak menyediakan konfigurasi lokal.[1], [3]

Langkah 2

Pengembang meminta diff berkas

Tampilan perubahan Reasonix menjalankan jalur Git diff untuk berkas yang dipilih. Tindakan UI ini merupakan interaksi pengguna yang disyaratkan CVE.[1], [3]

Langkah 3

Git menerapkan filter clean

Git menyiapkan konten untuk dibandingkan dan dapat memanggil filter clean yang dikonfigurasi. --no-ext-diff dan --no-textconv menonaktifkan mekanisme lain dan tidak menghentikan filter ini.[1], [3]

Langkah 4

Filter berjalan dengan hak pengguna

Perintah filter yang dikonfigurasi berjalan dalam konteks proses Reasonix. Dampak yang didokumentasikan adalah eksekusi perintah lokal dengan hak pengguna tersebut.[1], [2], [3]

Kode Sumber: Rentan vs Aman

Pembuat argumen ini bersifat ilustratif, bukan patch siap pakai. Pemanggil harus mendaftar semua driver yang dipilih oleh .gitattributes, .git/info/attributes, dan berkas atribut global/sistem, serta hanya menetapkan discoveryComplete setelah pemindaian lengkap berhasil. Fungsi ini memvalidasi nama yang diberikan dan membuat override konfigurasi baris perintah; fungsi ini tidak menemukan atau memverifikasi himpunan driver. Pemanggilan yang rentan dikutip dari pengungkapan GitLab; pola pertahanan merupakan sintesis orisinal dari panduan maintainer dan PR hardening yang telah digabungkan.[1], [3], [4], [5]

Cuplikan sumber: desktop/workspace_changes.go

IMPLEMENTASI RENTAN
// Pemanggilan sumber yang dikutip GitLab Threat Research; ini adalah titik pemanggilan, bukan fungsi lengkap.
args := []string{"-C", base, "diff", "--no-ext-diff", "--no-textconv", "--relative", "HEAD", "--", filepath.FromSlash(rel)}
PERBAIKAN AMAN & KUAT
// Builder argumen Go ilustratif, bukan patch vendor yang disalin persis.
package gitguard

import (
    "errors"
    "fmt"
    "path/filepath"
    "regexp"
)

// Pemanggil harus menemukan semua filter yang dipilih oleh atribut efektif dan memberikan himpunan lengkapnya.
// Helper ini hanya menetralkan kunci driver tersebut pada semua cakupan konfigurasi Git.
var filterDriverName = regexp.MustCompile(`^[A-Za-z0-9_-]{1,64}$`)

func hardenedDiffArgs(base, rel string, drivers []string, discoveryComplete bool) ([]string, error) {
    if !discoveryComplete {
        return nil, errors.New("cannot safely diff: filter-driver discovery failed")
    }
    args := []string{"-C", base}
    seen := map[string]struct{}{}
    for _, driver := range drivers {
        if !filterDriverName.MatchString(driver) {
            return nil, fmt.Errorf("cannot safely diff: unsupported Git filter driver name %q", driver)
        }
        // Nama subbagian Git config peka huruf besar-kecil: jangan ubah kapitalisasi nama driver.
        key := driver
        if _, ok := seen[key]; ok {
            continue
        }
        seen[key] = struct{}{}
        for _, setting := range []string{"clean", "smudge", "process", "required"} {
            args = append(args, "-c", "filter."+driver+"."+setting+"=")
        }
    }
    return append(args, "diff", "--no-ext-diff", "--no-textconv", "--relative", "HEAD", "--", filepath.FromSlash(rel)), nil
}

Daftar Periksa Penguatan Sistem Rekayasa

Sumber