FlawOpen

flawopen.com/Teardowns/cve-2026-87913-aws-security-agent-mcp-s3-bucket-ownership

● CVE-2026-87913 · CVSS 5.1 · Sedang
Riset Keamanan · FlawOpen

CVE-2026-87913: Kebocoran S3 MCP AWS

Bucket yang mudah ditebak dapat menerima arsip pemindaian privat di akun lain. Perbarui ke 0.2.0 dan verifikasi pemiliknya.[1], [2], [4]

💡 Penjelasan Sederhana (ELI5)

Bayangkan kurir yang hanya memastikan ada gedung di suatu alamat, tanpa memeriksa pemiliknya. Orang lain dapat mendaftarkan alamat itu lebih dahulu dan menerima paket. Perbaikan meminta S3 memastikan pemilik yang diharapkan saat pemeriksaan dan unggahan.[2], [1]

Konsep Kunci & Istilah

Server MCP
Layanan lokal yang menyediakan operasi sebagai tool untuk asisten AI; operasinya memakai izin proses server.[3]
Bucket S3
Kontainer Amazon S3 bernama global; nama tidak membuktikan akun AWS mana yang memilikinya.[2], [3]
ExpectedBucketOwner
Parameter permintaan S3 yang memeriksa ID akun AWS pemilik yang diharapkan sebelum operasi.[2], [8], [9]
CWE-283 dan CWE-341
Kelemahan MITRE untuk kepemilikan yang tidak diverifikasi dan nilai yang dapat ditebak; advisori mencantumkan keduanya.[8], [9]

Pemetaan kerangka kerja

Analisis Akar Masalah (Root Cause)

Server MCP AWS Security Agent membentuk nama bucket masukan pemindaian dari ID akun AWS pelanggan dan Region: security-agent-scans-<account-id>-<region>. AWS dan advisori maintainer menyatakan versi rentan hanya memeriksa keberadaan bucket, bukan kepemilikan akun pelanggan. Nama S3 bersifat global dan ID akun bersifat publik. Pihak lain yang lebih dahulu mendaftarkan nama tersebut dapat menerima arsip privat yang diunggah server; arsip dapat berisi kode, kredensial, dan status infrastruktur. Ini adalah kegagalan verifikasi kepemilikan sumber daya cloud dan nama yang mudah ditebak, bukan prompt injection model AI. Versi 0.1.0–0.1.5 terdampak; 0.2.0 menambahkan ExpectedBucketOwner pada operasi S3 dan gagal jika pemilik berbeda. Pembaruan tidak membebaskan nama yang telah didaftarkan pihak lain: verifikasi pemilik sebenarnya dan jangan lanjutkan pemindaian jika bucket milik pihak ketiga.

Nama bucket tidak membuktikan kepemilikannya

BatasKondisi yang terdokumentasiTindakan operator
Versi terdampakawslabs.security-agent-mcp-server versi 0.1.0 hingga 0.1.5 terdampak; versi 0.2.0 menambahkan pemeriksaan kepemilikan.Tingkatkan ke versi 0.2.0 atau lebih baru dan verifikasi versi paket yang sedang berjalan.
Nama bucket yang dapat diprediksiNama bucket pemindaian dibuat dari ID akun dan Region; akun AWS lain dapat mendaftarkannya lebih dahulu.Anggap nama yang cocok sebagai alamat, bukan bukti kepemilikan.
Unggahan lintas akunServer rentan dapat menerima bucket berdasarkan nama tanpa memverifikasi pemilik, lalu mengunggah arsip pemindaian privat ke sana.Verifikasi bucket dimiliki akun yang diharapkan sebelum memindai atau mengunggah.
Batas kepemilikan yang diperbaikiExpectedBucketOwner membuat S3 membandingkan pemilik saat pemeriksaan kepemilikan maupun saat unggah.Tingkatkan versi, verifikasi pemilik sebenarnya, dan hentikan pemindaian jika nama dimiliki pihak lain; peningkatan versi tidak memindahkan bucket.

Alur Serangan Langkah demi Langkah

Langkah 1

Permintaan pemindaian membawa kode

Klien AI meminta pemindaian; server lokal mengarsipkan workspace dengan identitas AWS yang dikonfigurasi.[3], [2]

Langkah 2

Tujuan dapat ditebak

Nama bucket berasal dari ID akun dan Region; ID bukan rahasia dan nama S3 berlaku global.[1], [2]

Langkah 3

Pemeriksaan hanya memastikan keberadaan

Server terdampak menerima bucket berdasarkan nama tanpa memastikan akun pelanggan memilikinya.[2], [1]

Langkah 4

Arsip dapat mencapai akun lain

Jika akun lain mendaftarkan nama lebih dahulu, ia dapat menerima arsip privat yang mungkin berisi data sensitif.[2], [1]

Kode Sumber: Rentan vs Aman

Kode ini skematis, bukan salinan persis. Keberadaan saja tidak cukup: S3 harus membandingkan akun pemilik yang diharapkan saat pemeriksaan dan penulisan. Ambil akun dari identitas AWS terautentikasi dan gagalkan operasi jika berbeda. Setelah pembaruan, periksa pemilik secara terpisah karena nama yang sudah terdaftar tidak dipindahkan atau dibebaskan. AWS mendokumentasikan ExpectedBucketOwner pada HeadBucket dan PutObject: ketidakcocokan membuat permintaan gagal dengan 403. Gunakan sebagai pengaman fail-closed, tetapi selidiki kesalahan akses ditolak melalui jalur pemeriksaan kepemilikan yang berwenang sebelum menyimpulkan bucket dimiliki pihak lain.[2], [8], [9]

Cuplikan sumber: Contoh AWS SDK berdasarkan advisori; bukan diff sumber yang verbatim.

IMPLEMENTASI RENTAN
# Bentuk rentan sederhana: nama diperiksa, tetapi pemiliknya tidak.
s3.head_bucket(Bucket=bucket_name)
s3.put_object(
    Bucket=bucket_name,
    Key=object_key,
    Body=archive_bytes,
)
PERBAIKAN AMAN & KUAT
# Kaitkan setiap operasi dengan akun yang seharusnya memiliki bucket.
expected_owner = sts.get_caller_identity()["Account"]
s3.head_bucket(
    Bucket=bucket_name,
    ExpectedBucketOwner=expected_owner,
)
s3.put_object(
    Bucket=bucket_name,
    Key=object_key,
    Body=archive_bytes,
    ExpectedBucketOwner=expected_owner,
)

Daftar Periksa Penguatan Sistem Rekayasa

Sumber