FlawOpen

flawopen.com/Teardowns/cve-2026-97662-aws-security-agent-mcp-git-argument-injection

● CVE-2026-97662 · CVSS v4 6.9 · Sedang
Riset Keamanan · FlawOpen

CVE-2026-97662: injeksi argumen Git pada AWS Security Agent MCP

CVE-2026-97662 memungkinkan referensi Git yang dipengaruhi pemanggil dalam diff scan AWS Security Agent MCP ditafsirkan sebagai opsi perintah, melewati pembatasan workspace, dan menulis file pada host. Perbarui ke versi 0.2.0 atau lebih baru.[1], [2]

Vektor CVSSCVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N
💡 Penjelasan Sederhana (ELI5)

Seorang petugas diminta mencari map berdasarkan label, tetapi menerima label yang diawali instruksi kontrol. Sistem arsip menjalankan instruksi itu alih-alih mencari map. Dalam kasus ini, referensi Git yang diawali tanda hubung dapat dianggap sebagai opsi. Menolak referensi kosong atau yang tampak seperti opsi sebelum menjalankan Git menutup batas input tersebut. Ini adalah penguraian opsi oleh Git, bukan eksekusi perintah shell secara sembarang.[2]

Konsep Kunci & Istilah

Server MCP
Proses lokal yang menyediakan alat bagi aplikasi AI melalui Model Context Protocol. Argumen alat masuk ke server sebagai data yang tidak tepercaya.
Injeksi argumen (CWE-88)
Program baris perintah menafsirkan input tidak tepercaya sebagai opsi atau pemisah, meskipun proses menerima daftar argumen alih-alih string shell.[2], [4]
Referensi Git
Nama atau ekspresi yang menunjuk commit atau tree, seperti main atau HEAD~1. Nilai yang diawali - dapat dibaca sebagai opsi.[2], [3]
Pembatasan workspace
Batas yang dimaksudkan agar operasi file alat tetap berada di direktori proyek yang dipilih. Batas ini tidak lengkap jika input mengubah arti perintah subprocess.[1], [3]

Pemetaan kerangka kerja

Analisis Akar Masalah (Root Cause)

AWS menjelaskan injeksi argumen kontekstual pada operasi diff scan: referensi yang diberikan ke pemindaian dapat ditafsirkan sebagai opsi baris perintah, bukan revisi Git. PR upstream mengonfirmasi bahwa start_diff_scan meneruskan base_ref ke git diff <base_ref> -- dan git archive; nilai kosong atau yang diawali tanda hubung dapat ditafsirkan berbeda. Ini bukan injeksi metakarakter shell: daftar argumen mencegah parsing shell, tetapi program yang dipanggil tetap dapat mem-parsing opsinya sendiri. Menurut AWS, masalah ini dapat membuat, menimpa, atau memotong file di luar workspace yang dimaksud, sebatas izin OS proses. Perbaikan yang digabung memvalidasi base_ref sebelum Git dan menolak nilai kosong serta nilai yang setelah trim diawali -; pengujian memastikan tidak ada subprocess maupun unggahan untuk input yang ditolak. Versi >=0.1.1 dan <0.2.0 terdampak; 0.2.0 memperbaikinya. Catatan CVE memberi CVSS 4.0 6,9 Sedang; GitHub Advisory juga mencantumkan CVSS 3.1 8,2 Tinggi. Payload eksploit tidak ditampilkan di sini.[1], [2], [3], [4]

Alur Serangan Langkah demi Langkah

Langkah 1

Agen memanggil alat diff scan

Server MCP lokal menerima base_ref yang dapat dipengaruhi pemanggil. Risiko bergantung pada alur yang memungkinkan repositori, konten, atau pengguna tidak tepercaya memengaruhi nilai tersebut; prompt injection saja tidak otomatis mencapai jalur kode ini.[2]

Langkah 2

Nilai diteruskan ke Git sebagai argumen posisi

Kode terdampak meneruskan referensi ke perintah Git diff dan archive. Tanda hubung di awal dapat membuat Git membacanya sebagai opsi meskipun Python tidak memakai shell.[2], [3]

Langkah 3

Parsing opsi Git melewati batas yang diasumsikan

Opsi yang dibuat untuk konteks ini dapat mengarahkan penulisan ke luar workspace. Dampak yang didokumentasikan adalah membuat, menimpa, atau memotong file yang dapat ditulis proses; jangkauannya bergantung pada izin dan alur.[1], [3]

Langkah 4

Tolak referensi berbahaya sebelum efek samping

Versi 0.2.0 memvalidasi base_ref sebelum Git, unggahan S3, atau pemeriksaan ruang agen. Perbarui dan jalankan proses MCP dengan hak minimum serta isolasi.[1], [3], [6]

Alur batas: teks revisi dan opsi Git

Alur data konseptual, bukan urutan perintah atau reproduksi exploit.

Dua parser, dua batas yang berbeda

Parsing shell
Array argumen mencegah shell menafsirkan nilai sebagai sintaks shell dan menutup batas ini.[3]
Parsing opsi Git
Git tetap mem-parsing tata bahasa baris perintahnya sendiri. Array argumen tidak mencegah ref yang dipengaruhi pemanggil ditafsirkan sebagai opsi; validasi sebelum menjalankan Git.[2], [3]
1

Pemanggil memengaruhi revisi

Alat diff scan menerima base_ref dari suatu alur kerja. Risiko hanya ada jika sumber yang tidak tepercaya dapat memengaruhi nilai tersebut.[2], [3]

2

Array argumen tetap mencapai parser Git

Python dapat mengirim setiap nilai secara terpisah dan menghindari parsing shell, tetapi Git tetap menafsirkan opsi baris perintahnya sendiri.[3], [2]

3

Asumsi batas workspace dapat gagal

Jika Git menafsirkan nilai sebagai opsi, keluaran berkas dapat keluar dari workspace yang dimaksud; cakupannya dibatasi izin OS proses MCP.[1], [2]

4

Validasi menutup batas masukan

Versi 0.2.0 menolak ref kosong dan yang menyerupai opsi sebelum menjalankan Git atau efek samping berikutnya. Masukan tidak lagi dapat memilih perilaku opsi Git; ref yang valid tetap memilih revisi yang diminta.[3], [6]

Kode Sumber: Rentan vs Aman

Perbandingan terfokus pada batas pemanggilan upstream, bukan salinan penuh scanner. Perubahan yang digabung memvalidasi referensi sebelum Git; pengujian memastikan nilai kosong dan berawalan tanda hubung tidak memulai subprocess atau unggahan. Daftar argumen mencegah parsing shell, tetapi tidak mencegah Git menafsirkan opsi. Cuplikan ini hanya menampilkan pemanggilan git diff; validasi yang sama harus melindungi setiap penggunaan base_ref, termasuk git archive.[3]

IMPLEMENTASI RENTAN
def start_diff_scan(path: str, base_ref: str):
    # Ref yang menyerupai opsi mencapai Git sebelum divalidasi.
    return subprocess.run(
        ["git", "diff", base_ref, "--"],
        cwd=path,
        check=False,
    )
PERBAIKAN AMAN & KUAT
def _validate_git_ref(base_ref: str) -> None:
    if not base_ref or not base_ref.strip():
        raise ValueError("base_ref must not be empty.")
    if base_ref.strip().startswith("-"):
        raise ValueError("base_ref must not start with '-'.")

def start_diff_scan(path: str, base_ref: str):
    _validate_git_ref(base_ref)  # Tolak sebelum memulai subprocess atau mengunggah berkas.
    return subprocess.run(
        ["git", "diff", base_ref, "--"],
        cwd=path,
        check=False,
    )

Daftar Periksa Penguatan Sistem Rekayasa

Sumber