Pencurian token GitHub 1-klik melalui bug VSCode
(blog.ammaraskar.com)- github.dev menggunakan token OAuth yang diterima dari github.com untuk membuka file, membuat PR, dan melakukan commit di VSCode browser, dan karena token ini tidak dibatasi ke repositori tertentu, token tersebut dapat membaca dan menulis ke seluruh repositori yang bisa diakses pengguna
- Webview VSCode diisolasi dengan iframe
vscode-webview://..., tetapi demi UX shortcut keyboard,keydowndari webview diteruskan ke jendela utama sebagai pesandid-keydown, sehingga skrip tidak tepercaya dapat mengirim event seolah-olah itu input keyboard pengguna - Input teks arbitrer tidak berhasil karena HTML
<input>, tetapi dengan menggabungkan shortcut bawaanCtrl+Shift+A, notifikasi instalasi extension yang direkomendasikan, local workspace extensions, dan keybinding kustom, perintah instalasi extension dapat dijalankan - PoC menjalankan JavaScript dari sel Markdown Jupyter notebook, menerima instalasi extension yang direkomendasikan, lalu memasang extension yang dipilih lewat keybinding baru, kemudian menampilkan token GitHub API dan daftar repositori privat
- VSCode desktop juga memiliki kerentanan yang sama, tetapi penyerang harus membujuk korban untuk meng-clone repositori dan membuka notebook, dan pengguna github.dev perlu menghapus data situs agar dialog konfirmasi awal muncul kembali sebagai langkah pertahanan
Ringkasan kerentanan
- github.dev membuka VSCode ringan yang berjalan di browser ketika URL repositori GitHub yang dapat diakses diubah dari
github.commenjadigithub.devatau saat item menu diklik - VSCode browser ini dapat melihat file repositori, juga dapat membuka repositori privat, serta bisa mengirim PR dan membuat commit
- github.com mengirim token OAuth ke github.dev melalui POST agar dapat berinteraksi dengan GitHub atas nama pengguna, dan token ini tidak dibatasi pada repositori tertentu yang sedang diakses pengguna
- Penyerang dapat mencuri token GitHub dengan hak baca-tulis hanya dengan klik tautan, termasuk akses ke repositori privat milik target
Isolasi webview dan masalah penerusan input keyboard
- VSCode webviews menggunakan
<iframe>dengan origin berbeda dari jendela utama VSCode untuk mengisolasi eksekusi JavaScript - Output Jupyter notebook dirender di dalam
<iframe>dengan originvscode-webview://..., sedangkan jendela utama Electron menggunakan originvscode-file://... - Berkat isolasi ini, notebook yang memakai tampilan HTML atau widget interaktif berbasis JavaScript tidak dapat memanggil API Node.js Electron atau API VSCode dari dalam iframe
- Fitur yang mengharuskan jendela utama dan webview bekerja sama, seperti pratinjau Markdown, saling bertukar pesan melalui API Window.postMessage()
- VSCode meneruskan event
did-keydownke jendela utama agar shortcut sepertiCtrl+Shift+Ptetap berfungsi meskipun fokus berada di dalam webview - Skrip tidak tepercaya di dalam webview dapat memicu event
keydownsecara langsung untuk menyamar seolah pengguna menekan tombol
Rantai serangan
Ctrl+Shift+Pmemang bisa membuka command palette, tetapi karena command palette memakai HTML<input>, pendekatan memasukkan string arbitrer tidak berhasil- Input seperti tombol arah dan
Enteryang diproses lewatkeydowntetap bisa digunakan, demikian juga kumpulan shortcut bawaan VSCode Ctrl+Shift+Aadalah keybinding default untuk “Notifications: Accept Notification Primary Action” dan menekan tombol utama pada notifikasi VSCode terakhir- Jika extension yang direkomendasikan dimasukkan ke
.vscode/extensions.json, VSCode akan menampilkan notifikasi instalasi, tetapi sistem publisher trust di VSCode 1.97 akan memunculkan dialog kepercayaan terpisah saat memasang extension dari publisher baru - Navigasi tombol dengan
Tabmemang dimungkinkan, tetapi pemrosesanEnterpada tombol “Trust Publisher & Install” terikat kekeydowntombol itu sendiri, sehingga jalur ini saja sulit dipakai untuk menyelesaikan instalasi - Local workspace extensions memungkinkan extension di
.vscode/extensionsdipasang langsung di workspace tepercaya, dan github.dev/web workspace selalu berada dalam status tepercaya - Jika local workspace extension dicoba dijalankan langsung, extension worker akan mengharapkan extension berasal dari
vscode-cdn.net, sehingga muncul error CSP - Sebagai gantinya, keybinding kustom dapat ditambahkan ke
package.jsonmilik local workspace extension, lalu keybinding itu dibuat memanggilworkbench.extensions.installExtensiondengan konteksskipPublisherTrust
Cara kerja PoC dan dampaknya
- Konfigurasi yang dibutuhkan adalah repositori yang berisi Jupyter notebook dan local workspace extension
- Sel Markdown notebook dapat menjalankan JavaScript melalui atribut
onerrorpada gambar - Payload menunggu sampai VSCode menampilkan notifikasi instalasi extension yang direkomendasikan, lalu mengirim event
Ctrl+Shift+Auntuk menerima aksi utama notifikasi tersebut - Setelah itu, payload menunggu sampai extension terpasang dan aktif serta keybinding kustom tersedia, lalu memicu
Ctrl+F1untuk menjalankan instalasi extension yang dipilih - Extension yang dipasang dalam PoC mengambil token GitHub API, meminta
https://api.github.com/user/reposuntuk mendapatkan repositori privat yang dapat diakses, lalu menampilkan token dan daftar repositori di kotak informasi - Setelah PoC dijalankan, data github.dev harus dihapus atau extension PoC harus dibuang, karena jika tidak, extension tersebut akan tetap aktif di semua halaman github.dev
- VSCode desktop juga memiliki kerentanan yang sama, tetapi penyerang harus membujuk korban untuk meng-clone repositori dan membuka notebook yang berisi payload skrip webview
- Jika webview yang dibuka korban memiliki XSS lain, maka di desktop hal itu pada praktiknya dapat berujung pada remote code execution penuh
Pertahanan dan faktor mitigasi
- Jika belum pernah memakai github.dev sebelumnya, ada satu dialog yang harus diklik saat masuk ke situs, sehingga memberi kesempatan untuk keluar dari halaman serangan
- Dengan menghapus cookie dan data situs lokal github.dev, dialog awal ini bisa muncul kembali
- Di Chrome, data terkait domain dapat dihapus dengan menekan ikon di bilah URL lalu masuk ke Cookies and site data > Manage on-device site data
- Jika pengguna sudah pernah melewati dialog github.dev dan belum membersihkan local storage browser, maka github.dev tidak memiliki perlindungan seperti token CSRF, sehingga tautan apa pun di internet dapat mengarahkan ke serangan ini
- VSCode tidak hanya mengandalkan isolasi iframe, tetapi juga memakai Content Security Policy yang ketat dan DOMPurify
- Karena pratinjau Markdown di halaman extension memakai
script-src 'none'untuk mencegah eksekusi JavaScript arbitrer, dampak yang lebih besar berupa desktop 1-klik RCE hanya dari tautan extension berhasil diblokir
Latar belakang pengungkapan dan timeline
- MSRC sebelumnya diam-diam memperbaiki laporan bug VSCode tanpa memberi kredit dan menandainya sebagai tidak berdampak keamanan
- Laporan bug XSS VSCode terbaru dari Starlabs juga ditandai tidak memenuhi syarat dan memiliki tingkat keparahan rendah
- Tim VSCode mungkin memang memerlukan lebih banyak waktu untuk menyeimbangkan UI/UX dan keamanan, tetapi pengungkapan penuh dipilih karena waktu dan upaya peneliti keamanan tidak seharusnya dianggap remeh
- Pada 2 Juni 2026, satu jam sebelum publikasi, rencana pengungkapan diberitahukan ke kontak lama di bagian keamanan GitHub
- Pada hari yang sama, kerentanan dipublikasikan dan juga didaftarkan di VSCode issue tracker
1 komentar
Komentar Hacker News
Rangkuman yang bagus, dan kalau dilihat lebih luas, cukup disayangkan bahwa editor VSCode yang di-embed di web itu sendiri sudah login ke GitHub
Terlepas dari ada tidaknya pertahanan berlapis, dosa asal itulah yang membuat permukaan serangannya jadi besar. Ini mirip dengan menaruh token GitHub API berhak penuh dalam bentuk plaintext di workstation agar bisa ditemukan paket NPM berbahaya
Idealnya, browser IDE berjalan dengan cakupan izin sementara per repositori atau token yang hanya bisa pull/push untuk repositori tersebut, dan sama sekali tidak memiliki sesi web github.com. Jika butuh seluruh UI web GitHub, kembali saja ke github.com, sementara github.dev dibiarkan sebagai layanan repositori tunggal
Namun itu tentu kurang nyaman bagi pengguna, sulit diimplementasikan, dan kemungkinan besar bertabrakan dengan asumsi-asumsi lama yang sudah tertanam di seluruh alat github.dev
github.dev juga perlu mempertimbangkan pendekatan ini dengan serius
[1] https://orca.security/resources/blog/hacking-github-codespac...
Yang lebih buruk, para pengembang pun tampaknya tidak terlalu peduli
keydownmana punDi desktop, mungkin lebih baik Electron mencegatnya langsung dan fitur ini dihapus, sedangkan di web rasanya memang harus dinonaktifkan secara bawaan
Saya juga tidak terlalu tahu apakah hosting Git lain punya fitur serupa
Sejujurnya agen LLM juga seharusnya begitu. Membiarkan LLM melakukan push langsung terasa ceroboh
Yang membuat serangan ini sangat rumit adalah bahwa ekstensi VSCode dijalankan dengan tingkat kepercayaan yang sama seperti editornya sendiri, dan kebanyakan pengembang memasang puluhan ekstensi tanpa pernah meninjau izinnya
Jika ada ekstensi berbahaya atau yang telah dibajak membocorkan token GitHub secara diam-diam, itu sulit diketahui tanpa pemantauan jaringan, dan ini menjadi alasan bahwa ekstensi seharusnya dijalankan dalam profil yang terisolasi
Cara terbaik adalah keluar dari GitHub dan pindah ke GitLab/Forgejo internal yang di-host sendiri, lalu memblokir GitHub sepenuhnya
Saya baru-baru ini mengalami hal yang mirip. Token GitHub dan token Cloudflare saya dicuri
Menurut saya, sekalipun keamanan ditangani dengan serius, jika waktunya cukup lama pada akhirnya kita tetap bisa kena. Yang terbaik adalah melakukan pemisahan dan mengendalikan cakupan dampaknya
Jangan percaya siapa pun dan apa pun, gunakan OrbStack, dan selalu bekerja dengan asumsi bahwa token pada akhirnya akan bocor
Alur kerja saya benar-benar hancur, tetapi untungnya pihak yang mengambil token itu tampaknya lebih mirip bot spam. Mereka membuat banyak halaman spam palsu dan mencoba menambang kripto
Kesan yang paling membekas adalah rasa telah diterobos. Semoga semuanya berhati-hati
Bagian tentang pengalaman buruk saat melaporkan bug VSCode ke MSRC lalu mereka diam-diam memperbaikinya begitu saja itu sangat khas MSRC. Sepertinya mereka sadar para peneliti toh tetap melapor gratis, jadi merasa tidak ada alasan untuk berubah
Saya tidak tahu detail spesifik kasus ini, tetapi dulu saya pernah mengelola program bug bounty lewat Bountysource dan HackerOne. Kadang laporan lebih dulu mengalir ke tim pengembang sebelum tim keamanan sempat mengevaluasinya sepenuhnya
Pada titik itu pengembang bisa saja memperbaikinya diam-diam. Terkadang karena kekhawatiran, rasional atau tidak, bahwa jika dikaitkan dengan bug keamanan hal itu akan terlihat buruk bagi mereka atau memengaruhi peluang promosi. Akibatnya, saat tim keamanan mencoba mereproduksi, kerentanannya sudah hilang
Dari sudut pandang MSRC, yang terlihat hanya bahwa langkah reproduksi yang diberikan sudah tidak berfungsi lagi. Riwayat bug internal atau apakah seseorang sudah menambalnya tidak terlihat. Jadi laporannya ditutup sebagai tidak valid, meskipun penemuan aslinya sah
Terima kasih karena pada dasarnya Anda menyumbangkan waktu yang dipakai untuk eksploit ini demi menunjukkan bahwa respons keamanan VS Code perlu diperbaiki. Anda sebenarnya bisa saja menyerah, tetapi masih tetap membantu
Saya benar-benar tidak paham kenapa lebih banyak developer tidak mencoba Neovim
Mungkin ini soal selera, tetapi saya suka konfigurasi kecil yang memungkinkan kita memahami apa yang terpasang dan apa yang sedang berjalan. Saat VSCode, browser IDE, ekstensi, sinkronisasi, token, dan plugin acak bercampur, jadi sulit mengetahui apa mengakses apa
Itu adalah fitur dari ekstensi Python resmi Microsoft, dan dalam hal lain itu satu-satunya ekstensi yang lumayan layak dipakai, tetapi ia memasang definisi tipe untuk versi library yang berbeda dari versi yang dipakai proyek saya. Itu terasa sangat mengkhawatirkan karena tampak seperti dengan santainya menjalankan kode pihak ketiga yang tidak diverifikasi, dan sepertinya juga tidak bisa dimatikan lewat pengaturan
Saya ingin bilang “sejak itu saya tidak pernah menoleh ke belakang”, tetapi sejujurnya selama 1~2 tahun terakhir Neovim mulai rutin merusak konfigurasi saya hampir di setiap upgrade. Sebenarnya tanda-tandanya sudah ada. Secara teknis sudah 10 tahun berlalu, tetapi nvim masih belum merilis versi stabil pertamanya, jadi kita tidak bisa benar-benar menyalahkan ketidakstabilannya, namun itu patut diingat
Saya sedang mempertimbangkan kembali ke Vim murni. Saya akan kehilangan banyak fitur kenyamanan, tetapi saya ingin lebih jarang harus men-debug fitur yang rusak saat sedang bekerja
Tidak perlu memasang banyak plugin atau memakai sesuatu seperti SpaceVim. Mungkin Anda akan suka kalau mencobanya
Perlu waktu untuk terbiasa dengan nvim, tetapi setelah terbiasa, ia lebih cepat. Tetap saja, ini menjelaskan kenapa banyak orang bertahan di zona nyaman mereka
Pengungkapan publik adalah langkah yang tepat. Terlalu banyak orang punya keluhan terhadap MSRC, dan seperti situasi Nightmare Eclipse, sekarang rasanya mulai meluap
Jika pengungkapan seperti ini terus menumpuk, mungkin MSRC akan bercermin dan sadar bahwa merekalah masalahnya. Kemungkinannya tampak kecil, tetapi kita masih boleh berharap
Meski begitu, menurut saya setidaknya ia seharusnya mencoba, atau memberi tahu beberapa hari sebelum dipublikasikan. Kita tidak pernah tahu apa yang akan terjadi
Tulisannya sangat bagus, tetapi bagian akhir agak membingungkan buat saya. Saya ingin memastikan apakah pemahaman saya benar
Penulis mengatakan bahwa karena sistem kepercayaan publisher yang baru, ekstensi berbahaya tidak bisa dipasang langsung hanya dengan trik shortcut, dan bahwa ini bisa dilewati dengan ekstensi workspace lokal yang tidak memiliki pemeriksaan publisher, tetapi CSP memblokirnya
Solusinya tampaknya adalah memasang ekstensi workspace lokal yang membinding shortcut “install extension tanpa verifikasi publisher”
Jadi saya penasaran apakah 1) ini berarti dibutuhkan dua ekstensi. Yang pertama adalah ekstensi lokal yang hanya melakukan key binding, dan yang kedua adalah ekstensi berbahaya yang sebenarnya, yang karena CSP tidak perlu lokal dan pada praktiknya juga tidak bisa lokal, dan 2) apakah CSP hanya memblokir JS dari ekstensi lokal, tetapi tidak memblokir
package.jsonatau kemampuan menambahkan shortcutUntuk eksekusi paling langsung, Anda bisa mencoba memasukkan
my-extension/extension.js, tetapi itu diblokir oleh CSP. Namun karenascript-srcCSP hanya memblokir skrip, mengambilpackage.jsontetap diizinkan. Jadi itu dimanfaatkan untuk menambahkan key bindingSituasi MSRC benar-benar sulit dipercaya
Mungkin ada materi yang lebih baik, tetapi saya rasa video The Primeagen ini adalah bahan pengantar yang bagus
https://www.youtube.com/watch?v=9kxx5xp5nTQ
Saya punya sedikit nitpick pada bagian “Satu-satunya cara untuk mengizinkan perilaku ini adalah dua halaman web dari origin berbeda bekerja sama melalui API
Window.postMessage()”iframe atau jendela induk juga bisa berkomunikasi dengan mengubah properti
location.anchor