Backdoor Cursor Marketplace: Masalah Trust di VS Code Fork
Backdoor Claude Code di Cursor Marketplace menunjukkan VS Code fork tidak mewarisi model trust Microsoft. Cek ini sekarang.

Seorang developer membuka Cursor di Selasa pagi, melihat ada update untuk ekstensi Claude Code, lalu membiarkannya terpasang. Tidak ada yang terlihat berbeda. Ekstensinya jalan, asisten AI-nya berfungsi, dan menjelang makan siang mesin itu sudah menyimpan public key Ed25519 milik penyerang di ~/.ssh/authorized_keys, ada reverse SSH tunnel yang mengirim beacon ke server di internet, dan LaunchAgent yang menyamar sebagai proses sistem Apple untuk menjaga semuanya tetap hidup setelah reboot. Itulah backdoor Cursor Marketplace yang diungkap Phorion, dan ini demonstrasi paling jelas sejauh ini untuk sesuatu yang sudah lama digerutukan orang-orang security: VS Code fork memang mewarisi codebase Microsoft, tapi tidak mewarisi model trust Microsoft.
Saya sudah banyak menghabiskan karier untuk incident response di mesin developer, dan insiden ini terasa menusuk karena betapa biasa mekanisme distribusinya. Tidak ada phishing. Tidak ada zero-day. Cuma bundle ekstensi yang dimodifikasi, versi 2.1.312 dan 2.1.313, yang dipublikasikan ke marketplace yang secara default dipercaya developer karena kelihatan seperti hal yang sudah mereka percaya. Kanal resmi Anthropic bersih. Seseorang memakai akses ke pipeline publikasi Cursor untuk merilis salinan ekstensi yang sudah dimodifikasi, padahal Anthropic tidak pernah membangunnya untuk registry itu. Radius dampaknya mencakup setiap pengguna Cursor yang auto-update dalam jendela sebelas jam.
Apa Sebenarnya yang Dilakukan Backdoor Ini
Implant-nya berupa immediately invoked function expression yang ditempelkan di depan bundle extension.js yang sudah di-minify. Semua yang ada setelah prefix yang disisipkan terlihat seperti ekstensi normal: export activate dan deactivate yang sama, kode UI yang sama, string yang sama. Bagian inilah yang seharusnya bikin Anda khawatir kalau strategi deteksi Anda hanya "diff bundle dengan upstream". Bagian jahatnya hanya beberapa ratus byte JavaScript tambahan yang menempel di atas file legit yang panjangnya megabyte. Kode ini jalan begitu Node me-load modul, sebelum callback activate milik ekstensi terpanggil. User tidak perlu klik apa pun, memanggil Claude, atau berinteraksi dengan ekstensi sama sekali.
Payload-nya sendiri adalah pekerjaan empat tahap, dan jujur saja, eksekusinya rapi:
- Penanaman key. Menambahkan public key Ed25519 yang dikontrol penyerang, diberi komentar
svc-telemetry, ke~/.ssh/authorized_keysdengan permission 0700/0600 yang benar. - Mengaktifkan SSH. Memastikan sshd berjalan: systemctl di Linux, Remote Login di macOS, OpenSSH Server lewat PowerShell di Windows.
- Reverse tunnel. Membuka koneksi SSH keluar ke server yang dikontrol operator dengan
-R *:0:localhost:22, sehingga penyerang bisa masuk lewat tunnel ke port 22 korban dan login memakai key yang sudah ditanam. Tidak perlu protokol C2 custom, SSH adalah C2-nya. - Persistence dan recon. User LaunchAgent bernama
com.apple.sysmond.plistdi macOS, entri cron @reboot di Linux, dan fallback folder Startup di Windows. Lalu satu kali beacon berisi hostname, username, email git, IP publik, dan sampai empat puluh nama environment variable yang cocok dengan/KEY|TOKEN|SECRET|PASS|AWS|GCP/i.
Item terakhir itu pintar dengan cara yang layak dipahami. Beacon-nya tidak mencuri AWS secret key Anda, melainkan mencuri fakta bahwa Anda punya satu. Ini inventaris target. Operator mendapat daftar mesin mana yang dimiliki cloud engineer dengan kredensial aktif di environment-nya, dan itulah orang yang akan mereka datangi pertama lewat tunnel.
Bug macOS yang Tidak Sengaja Menyelamatkan Orang
Ini detail yang menurut saya lucu gelap sebagai incident responder: jalur aktivasi malware di macOS rusak karena kesalahan scripting klasik. Kodenya menjalankan systemsetup -getremotelogin sebagai user tanpa privilege dan hanya mencoba menyalakan Remote Login jika output-nya cocok dengan /Off/i. Tapi di macOS, perintah itu menolak jalan tanpa akses administrator. Ia mencetak "You need administrator access to run this tool... exiting!" ke stdout, lalu keluar dengan status 0.
// what the malware effectively does
var rl = ex("systemsetup -getremotelogin 2>/dev/null", 4000);
if (/Off/i.test(rl)) {
det("sudo -n systemsetup -setremotelogin on >/dev/null 2>&1");
}
String error itu tidak mengandung "Off", jadi regex gagal, jadi langkah aktivasi tidak pernah jalan. Script menganggap "saya tidak punya izin untuk mengecek apakah SSH mati" sebagai "SSH sudah menyala". Exit code 0 dari perintah yang gagal adalah salah satu jebakan tertua dalam shell scripting, dan kali ini justru menjebak penulis malware, bukan sysadmin. Di Mac yang Remote Login-nya belum aktif, reverse tunnel tetap terkoneksi ke luar, tapi apa pun yang diteruskan balik akan membentur port 22 yang tertutup. Key dan persistence tetap ditanam, jadi mesin tetap terkompromi, tapi jalur akses interaktifnya mati sejak awal.
Jangan merasa aman karena ini. Kalau user sudah mengaktifkan Remote Login, atau kapan pun nanti menyalakannya, key yang ditanam sudah menunggu di authorized_keys. Jalur Windows punya bug serupa (perintah PowerShell dialirkan lewat helper yang hardcode /bin/sh), dan logika cron Linux bisa menghapus crontab user yang sudah ada saat dijalankan berulang. Malware yang ditulis manusia punya bug manusia. Malware bulan depan tidak akan begitu.
Mengapa Marketplace Fork Tidak Bisa Mewarisi Model Trust Microsoft
Ini poin struktural, dan saya ingin para engineering lead benar-benar memikirkannya. Saat Anda memasang ekstensi dari Visual Studio Marketplace resmi, ada pipeline nyata di baliknya: akun publisher dengan verifikasi domain, scanning saat publikasi, proses takedown, dan sebuah perusahaan dengan departemen legal di ujung lainnya. Sistem ini jauh dari sempurna, ekstensi berbahaya pernah lolos juga, tapi ia adalah sebuah sistem.
VS Code fork seperti Cursor tidak bisa memakai marketplace itu karena alasan lisensi, jadi mereka mengarah ke registry alternatif seperti Open VSX atau infrastruktur sendiri. UI editornya sama persis dengan yang sudah familiar. Halaman ekstensinya menampilkan nama yang sama, ikon yang sama, dan string publisher yang masuk akal. Tapi setiap kontrol yang membuat marketplace asli bisa dipercaya sudah diimplementasi ulang, atau malah tidak ada. Siapa yang memverifikasi publisher? Siapa yang memindai bundle? Apakah artifact dibangun dari repo source yang diklaim, dan bisakah Anda mengeceknya? Dalam insiden ini, versi yang dimodifikasi ternyata tidak pernah ada di registry Microsoft, hanya hidup di fork itu sendiri. Trust-nya murni visual.
Kita sudah pernah menonton film yang sama di dunia package registry. Kompromi PyPI LiteLLM berhasil karena akses publikasi adalah titik lemahnya, bukan kodenya. Ekstensi bahkan lebih buruk dari package dalam satu hal penting: tidak ada budaya lockfile, tidak ada reproducibility ala npm ci, tidak ada hash pinning. Editor auto-update secara diam-diam, dan seperti yang ditemukan salah satu komentator Hacker News, delay auto-update VS Code bahkan tidak berlaku untuk "trusted publisher", sebuah daftar yang tidak bisa Anda konfigurasi. Kumpulan ekstensi Anda adalah dependency tree hidup yang tidak di-pin, jalan dengan privilege user penuh Anda, dan memperbarui dirinya sendiri saat Anda tidur.

AI Coding Tool adalah Eskalasi Privilege yang Anda Pilih Sendiri
Lepaskan drama marketplace dan lihat apa target sebenarnya. Ekstensi AI coding bukan tema warna. Ia berjalan dengan permission IDE, yang artinya permission Anda, dan seluruh tugasnya adalah membaca source tree Anda, menyimpan kredensial API Anda, dan makin sering menjalankan perintah shell atas nama Anda. Saat kami menulis tentang bagaimana CLI coding agentic menangani permission, tema yang berulang adalah agent yang berguna dan agent yang berbahaya dipisahkan oleh kebijakan, bukan kemampuan. Ekstensi yang bisa menjalankan child_process hanya berjarak satu publikasi buruk dari menjalankan apa pun.
Seorang komentator merangkumnya dengan blak-blakan: semua orang yang memakai tool ini pada dasarnya menjalankan curl-pipe-bash setiap hari, padahal kita menghabiskan satu dekade mengingatkan junior dev untuk tidak melakukan itu. Ini hiperbola, tapi tidak terlalu berlebihan. Bedanya antara curl | bash dan ekstensi agentic yang auto-update hanyalah ekstensi itu punya UI yang lebih bagus. Saya sudah beberapa kali berargumen bahwa CLI tool seharusnya tidak memasang background daemon secara default. Insiden ini adalah contoh ketika daemon dipasang oleh orang lain dan Anda tidak pernah memberi persetujuan sama sekali. Proses ssh yang tetap hidup setelah IDE ditutup adalah pola perilaku yang selalu saya tandai saat code review, dan di sini ia dikirim penyerang lewat kanal update yang tepercaya.
Cara Mengecek Fleet Anda Sekarang
Kalau ada orang di organisasi Anda yang memakai Cursor, perlakukan ini sebagai insiden yang sedang berjalan, bukan sekadar berita. Indikator sinyal tinggi, langsung dari write-up forensik:
# macOS / Linux: the planted key is the cleanest signal
grep -s svc-telemetry ~/.ssh/authorized_keys && echo "IMPACTED" || echo "key not found"
# Check persistence artifacts
ls ~/Library/LaunchAgents/com.apple.sysmond.plist 2>/dev/null # macOS
ls ~/.config/.smt ~/.config/.smtk 2>/dev/null # macOS + Linux
crontab -l 2>/dev/null | grep -F .smt # Linux @reboot entry
# Windows (PowerShell): check both authorized_keys locations
Select-String svc-telemetry "$HOME\.ssh\authorized_keys",
"C:\ProgramData\ssh\administrators_authorized_keys" -ErrorAction SilentlyContinue
# Live tunnel: look for detached ssh with remote forwarding
ps aux | grep -E 'ssh.*-R' | grep -v grep
Beberapa catatan hunting dari pengalaman. Pertama, cek fingerprint key, jangan hanya komentarnya. Implant ini melakukan dedup berdasarkan string komentar svc-telemetry, dan upaya cleanup mungkin juga begitu. Kedua, file tunnel key ada di direktori temp dengan nama seperti .stk_ diikuti sepuluh karakter hex yang diturunkan dari MD5 hostname plus path home. Nilainya deterministik per mesin, jadi Anda bisa menghitung nama file persisnya dan menyapu mesin untuk mencarinya. Ketiga, telemetry proses EDR tidak akan menampilkan percobaan aktivasi di macOS untuk user standar, karena karena bug tadi perintahnya tidak pernah benar-benar jalan. Tidak adanya systemsetup -setremotelogin di log Anda tidak berarti tidak ada kompromi. Key dan LaunchAgent adalah ground truth-nya.
Kalau Anda menemukan key-nya, mesin itu harus masuk perlakuan IR penuh: rotasi setiap kredensial yang nama environment variable-nya mungkin sudah di-beacon (yaitu hampir semuanya, regex-nya menangkap AWS, GCP, dan apa pun dengan KEY atau TOKEN di namanya), cabut akses mesin tersebut, lalu reimage. Jangan hanya menghapus key lalu menganggap selesai. Operator punya, atau mencoba punya, akses shell interaktif, dan Anda tidak bisa menghitung apa saja yang mereka sentuh hanya dari kode implant. Di sinilah titik buta dalam logging autentikasi cloud bikin repot. Cek audit log cloud Anda untuk penggunaan console atau API dari rentang waktu antara update ekstensi dan pengungkapan, dengan kunci berdasarkan kredensial user yang terdampak.

Hardening: Kendalikan Editor, Bukan Cuma Ekstensinya
Setelah insiden, semua orang bertanya apa yang harus diubah. Posisi saya, dan saya siap mempertahankannya: Anda tidak akan pernah bisa mengaudit jalan menuju ekosistem ekstensi yang aman, jadi Anda harus melakukan containment. Kita sudah membahas trade-off umumnya di containment vs monitoring untuk AI agent, dan insiden ini adalah studi kasus untuk sisi containment. Monitoring tidak memberi tahu apa-apa di sini sampai sebuah firma keamanan pihak ketiga kebetulan membedah bundle-nya.
- Pin versi ekstensi dan matikan auto-update untuk apa pun yang punya permission luas, dan terapkan aturan yang sama di seluruh fork. Ya, Anda akan kena update fatigue. Itu jauh lebih murah daripada incident response.
- Egress filtering di workstation developer. Seluruh model akses di sini bergantung pada koneksi SSH keluar ke IP VPS. Kalau mesin dev Anda tidak bisa membuka port 22 keluar secara bebas, tahap tunnel akan mati. Hampir tidak ada yang melakukannya, padahal ini akan sepenuhnya melumpuhkan implant ini.
- Pantau state SSH sebagai canary. Beri alert saat Remote Login menyala, ada key baru di authorized_keys, atau proses sshd berjalan di mesin yang seharusnya tidak menjalankan sshd.
- Inventarisasi tooling AI Anda seperti Anda menginventarisasi server. Ketahui ekstensi dan CLI agent mana yang sudah disetujui, permission apa yang mereka pegang, dan dari marketplace mana mereka berasal. Kalau jawaban untuk "instalasi Cursor kita pakai registry yang mana" hanyalah angkat bahu, itu proyek untuk kuartal depan Anda.
- Utamakan agent yang berjalan di sandbox atau container bila memungkinkan, dengan kredensial yang disuntikkan per sesi, bukan tersedia secara ambient di environment. Scraping nama env oleh beacon bekerja justru karena kita membiarkan secret tergeletak di environment proses.
Extension marketplace tanpa pipeline verifikasi sendiri bukanlah marketplace, melainkan file host dengan tombol install.
Kesimpulan yang Tidak Nyaman
Anthropic tidak dibobol. Marketplace Cursor yang dibobol, dan brand Anthropic tetap ikut terkena dampaknya, karena bagi developer ekstensi adalah produknya, siapa pun yang mempublikasikan build mana pun. Inilah ekonomi ekosistem fork: cara termurah untuk menyerang target bernilai tinggi adalah menyerang registry terlemah yang dipercaya penggunanya. Asisten AI coding berada di titik temu yang sempurna: basis instalasi yang besar, privilege lokal maksimal, kredensial di mana-mana, dan supply chain yang mem-fork dan me-host ulang artifact-nya di berbagai registry dengan postur keamanan yang sangat berbeda.
Insiden ini berakhir dengan versi berbahaya ditarik dalam sekitar sebelas jam, dan bug macOS membatasi kerusakannya. Responsnya sudah cukup baik. Masalahnya ada di arsitektur, dan itu belum berubah: editor Anda adalah package manager yang menjalankan semua yang ia pasang atas nama Anda, meng-update dirinya diam-diam, dan dalam makin banyak setup mengambil package dari registry yang tidak pernah dinilai tim security Anda. Perbaiki aturan egress, pin ekstensinya, dan inventarisasi agent-nya. Serangan publisher berikutnya tidak akan punya bug regex yang menyelamatkan user Anda.


