- Berbilang keluaran yang dikompromikan daripada @7nohe/openapi-react-query-codegen telah menyuntik perisian hasad ke dalam projek menggunakan cangkuk berasaskan Pertanyaan TanStack.
- Penyerang itu menyalahgunakan binding.gyp sandbox escape dan skrip prapasang untuk melaksanakan muatan JavaScript yang dikaburkan semasa pemasangan npm.
- Muatan memperoleh kelayakan awan dan pembangun yang luas, menyahsusutkannya ke repositori GitHub yang dikawal oleh penyerang.
- Token yang dicuri kemudiannya digunakan untuk sebarkan perisian hasad ke lebih banyak pakej npm dan repo GitHub, meracuni rantaian bekalan JavaScript yang lebih luas.
Bagi pasukan yang bergantung pada TanStack Query sebagai pakej npm pilihan mereka untuk mengurus keadaan pelayan dalam React dan rangka kerja bahagian hadapan yang lain, insiden rantaian bekalan baru-baru ini menunjukkan betapa cepatnya kepercayaan itu boleh terjejas. Alat pendamping yang popular, yang dibina khusus untuk menjana cangkuk TanStack Query yang selamat jenis daripada skema OpenAPI, telah dijadikan senjata secara senyap dan dihantar ke daftar npm dengan muatan perisian hasad yang canggih.
Penyelidik keselamatan menggambarkan serangan itu sebagai kempen gaya TeamPCP yang menggunakan semula banyak corak sandiwara dan teknikal yang dilihat dalam insiden terdahulu. Walau bagaimanapun, kali ini tumpuannya adalah tepat pada pembangun yang membentuk lapisan data mereka menggunakan pakej @7nohe/openapi-react-query-codegen, utiliti yang menjanjikan untuk menjimatkan masa dengan menjana cangkuk Pertanyaan TanStack secara automatik dan bukannya menulis boilerplate dengan tangan.
Bagaimana penjana kod Pertanyaan TanStack menjadi kenderaan penghantaran perisian hasad
Pakej di tengah-tengah insiden ini, @7nohe/openapi-react-query-codegen , direka bentuk untuk mengambil spesifikasi OpenAPI dan memancarkan cangkuk yang ditaip sepenuhnya yang serasi dengan TanStack Query. Dengan lebih 150,000 muat turun mingguan, ia berada dalam laluan kritikal bagi banyak pasukan yang menyeragamkan TanStack Query untuk mengatur pengambilan, penyimpanan caching dan penyegerakan data bahagian belakang dalam bahagian hadapan berasaskan React mereka.
Menurut bedah siasat, penyerang berjaya menjejaskan kedua-dua pakej npm dan repositori GitHubnya . Pelanggaran itu dicapai dengan mengeksploitasi kerentanan dalam salah satu aliran kerja GitHub Actions projek, yang bermaksud binaan berniat jahat masih kelihatan berasal dari saluran paip CI yang sah dan dihantar dengan pengesahan asal-usul yang sah. Pengesahan kriptografi tersebut, biasanya isyarat kepercayaan yang kuat untuk pengguna npm, menjadi mengelirukan sebaik sahaja aliran kerja itu sendiri berada di bawah kawalan musuh.
Dalam tempoh masa yang sempit sekitar dua puluh minit, penyerang menerbitkan sepuluh versi pakej yang diracuni ke npm, setiap satunya mengandungi kod yang direka untuk melaksanakan semasa pemasangan dan menjalankan muatan perisian hasad berbilang peringkat. Keluaran yang terjejas merangkumi beberapa versi kecil dan tampalan, yang semuanya kini harus dianggap sebagai tidak dipercayai.
- @7nohe/openapi-react-query-codegen@0.5.4
- @7nohe/openapi-react-query-codegen@0.5.5
- @7nohe/openapi-react-query-codegen@1.6.3
- @7nohe/openapi-react-query-codegen@1.6.4
- @7nohe/openapi-react-query-codegen@2.2.1
- @7nohe/openapi-react-query-codegen@2.2.2
- @7nohe/openapi-react-query-codegen@3.0.3
- @7nohe/openapi-react-query-codegen@3.0.4
- @7nohe/openapi-react-query-codegen@0.0.0-365d4eb738d3146583431948d3ba6e27a32556be
- @7nohe/openapi-react-query-codegen@0.0.0-ec7876d6c917dad516ba69bbfafc948b834bf0ab
Semua varian ini berkongsi tujuan asas yang sama: memanfaatkan populariti pakej di kalangan pengguna TanStack Query untuk mendapatkan pelaksanaan kod semasa pemasangan npm dan kemudian tersebar melalui rantaian bekalan JavaScript yang lebih luas.
Muatan "Trinitit" dan helah pelaksanaan masa pemasangannya
Perisian hasad itu mengenal pasti dirinya dengan label umpatan “Trinitit: Ditaja oleh Kesan Pratonton 2”, rujukan kepada bahan berkaca yang dibentuk oleh ujian nuklear. Nama skrip dalaman terdahulu seperti is_it_this_simple.js memberi bayangan tentang sikap sambil lewa penyerang, tetapi teknik yang mendasarinya sama sekali tidak ringkas.
Cangkuk pelaksanaan utama bergantung pada a binding.gyp sandbox escapeDalam projek Node.js biasa, binding.gyp digunakan untuk mengkonfigurasi addon asli yang dikompilasi oleh node-gyp, tetapi di sini ia dijadikan senjata. Apabila npm menemui fail binding.gyp, node-gyp menilai failnya conditions medan menggunakan Python. Penyerang memasukkan ekspresi Python yang dibina dengan teliti dalam medan tersebut, mengeksploitasi hierarki kelas Python untuk keluar daripada kotak pasir yang dijangkakan dan menjalankan arahan shell sewenang-wenangnya.
Dalam pakej yang dikompromi, ungkapan syarat sangat dikaburkan dengan Unicode dan hex escapesSetelah dinyahkod, ia menjalankan sistem dalaman Python __subclasses__ pokok untuk mencari lokasi catch_warnings kelas, menggunakannya sebagai pangsi untuk mencapai __builtins__, mengimport os modul dan akhirnya memanggil os.system() untuk melancarkan muatan utama dengan Node. type Medan dalam binding.gyp dikodkan heks sebagai none, jadi tiada binaan asli tulen dicuba; konfigurasi wujud semata-mata untuk menyeludup masuk satu arahan shell.
Pendekatan ini bermaksud pakej boleh laksanakan kod berniat jahat semasa pemasangan walaupun tiada keterangan yang jelas preinstall skrip yang ditakrifkan dalam package.json. Walau bagaimanapun, tidak semua versi yang diracuni bergantung pada helah yang tepat ini. Dua binaan pra-keluaran menggunakan cangkuk pra-pemasangan yang lebih mudah: satu melaksanakan skrip Node bernama nu.js secara langsung, manakala yang lain mengambil masa jalan Bun melalui wget paip ke bash dan kemudian menjalankan nama yang sesuai is_it_this_simple.jsVersi kemudian menggabungkan kedua-dua kaedah, menghantar binding.gyp yang berniat jahat dan a preinstall entri yang menunjuk ke muatan JavaScript utama yang sama untuk redundansi.
Lapisan pengaburan dan pengelakan kotak pasir dalam muatan JavaScript utama
Sebaik sahaja hook awal diaktifkan, serangan akan beralih kepada fail JavaScript yang besar bernama 3FWCvzduYZg.js , yang diletakkan dalam root pakej npm. Dengan saiz kira-kira 5.4 MB dan dikurangkan kepada satu baris, skrip direka bentuk untuk menjadi selegap mungkin sepintas lalu, dan analisis lanjut menunjukkan ia dilindungi oleh beberapa lapisan penyulitan dan pengaburan yang berbeza.
Lapisan paling luar terdiri daripada Tatasusunan integer 1.6 juta elemen, dinyahsulit dengan XOR mudah terhadap pemalar 29. Penyahsulitan itu menghasilkan skrip sekunder yang tugasnya adalah untuk mendapatkan masa jalan Bun secara senyap, menyimpannya di bawah nama fail sementara dengan trinnyyyy-XXXXX corak dalam direktori sementara sistem, dan kemudian gunakan Bun untuk melaksanakan muatan teras sebenar. Teras itu sendiri dibalut dengan penyulitan AES‑128‑GCM dan kemudian melalui cipher tersuai di atas teknik pengaburan JavaScript standard, termasuk yang dilihat dalam alat popular seperti obfuscator.io.
Tidak dibongkar sepenuhnya, muatan berlapis-lapis ini mendedahkan gabungan keupayaan: penuai kelayakan yang menyasarkan pelbagai platform awan dan pembangun, komponen cacing yang dapat menyebarkan jangkitan ke sasaran baharu dan saluran arahan yang merosakkan. Sebelum mana-mana daripadanya diaktifkan, skrip melakukan beberapa pemeriksaan persekitaran untuk mengelakkan kotak pasir dan alat keselamatan, keluar secara senyap jika keadaan petunjuk tertentu dipenuhi.
Antara pemeriksaan tersebut ialah penunjuk lokasi, persekitaran dan sistem fail biasanya dikaitkan dengan persekitaran penyelidikan. Perisian hasad akan terpadam jika lokasi sistem adalah Rusia, jika direktori milik produk keselamatan titik akhir seperti CrowdStrike, SentinelOne atau Carbon Black terdapat, jika direktori kerja semasa sepadan dengan laluan yang digunakan oleh alat pengimbasan rantaian bekalan yang diketahui, atau jika pembolehubah persekitaran mengandungi kelayakan palsu yang digunakan oleh pengimbas keselamatan. Ia juga melihat GITHUB_REPOSITORY_OWNER dan kehadiran alat pengerasan seperti StepSecurity harden-runner, mengelakkan akaun GitHub yang diketahui milik penyelidik keselamatan.
Apa yang dicuri oleh perisian hasad daripada persekitaran pembangunan berasaskan Pertanyaan TanStack
Sebaik sahaja pemeriksaan persekitaran diluluskan, perisian hasad akan mula menuai kelayakan dengan jaringan yang luas. Walaupun pakej asal dibingkaikan sebagai pembantu untuk pengguna TanStack Query, permukaan sasaran sebenar menjangkau jauh melangkaui satu pustaka, menyentuh hampir setiap lapisan rantaian alat dan tindanan awan pembangun JavaScript moden.
Di pihak pembangun, muatan mengimbas untuk Token akses peribadi GitHub dalam pelbagai format, termasuk token klasik bermula dengan gho or ghp dan token berbutir halus yang lebih baharu bermula dengan github_pat_Pada pelari GitHub Actions, ia juga meminta token OpenID Connect melalui dokumen yang didokumenkan ACTIONS_ID_TOKEN_REQUEST_TOKEN dan ACTIONS_ID_TOKEN_REQUEST_URL pembolehubah persekitaran, memberikan penyerang laluan untuk menganggap identiti beban kerja dan bukannya rahsia statik sahaja.
Skrip kemudiannya beralih kepada daftar bahasa umum. Ia berbunyi token npm, PyPI dan RubyGems daripada fail konfigurasi seperti ~/.npmrc, imbasan untuk projek-tempatan tambahan .npmrc fail dan percubaan untuk mengesahkan token pembawa npm yang ditemui dengan memanggil /-/whoami titik akhir pada pendaftaran awam. Corak serupa digunakan untuk PyPI dan RubyGems, melombong data pengesahan dan mengesahkan bahawa setiap token boleh berjaya berhubung dengan pendaftaran masing-masing sebelum mengekstraknya.
Jejak awan lebih besar lagi. Di Amazon Web Services, perisian hasad menyenaraikan pembolehubah persekitaran seperti AWS_ACCESS_KEY_ID dan AWS_SECRET_ACCESS_KEY, menghuraikan ~/.aws/credentials dan ~/.aws/config, dan membuat pertanyaan pada Perkhidmatan Metadata Tika EC2 di 169.254.169.254, lebih suka IMDSv2 tetapi berundur mengikut keperluan. Untuk beban kerja kontena, ia bercakap dengan titik akhir metadata ECS di 169.254.170.2Sebarang kelayakan atau token sementara yang dipulihkan diuji terhadapnya sts:GetCallerIdentity untuk mengesahkan kesahihan sebelum beratur untuk pengekstrakan penapisan.
Logik yang setanding wujud untuk penyedia awan lain. Skrip boleh mengumpulkan Kelayakan klien Azure dan identiti terurus, Termasuk AZURE_CLIENT_ID, AZURE_CLIENT_SECRET dan AZURE_TENANT_ID, dan kemudian akses Azure Key Vault, Azure Resource Manager dan Microsoft Graph setelah disahkan. Untuk Google Cloud, ia mencari GOOGLE_APPLICATION_CREDENTIALS fail, membuat pertanyaan pada pelayan metadata GCP di metadata.google.internal dan, apabila boleh, menggunakan token yang terhasil untuk memanggil Pengurus Rahsia Google. Pelaksanaan HashiCorp Vault juga ada dalam senarai: muatan mencari alamat dan token Vault melalui pembolehubah persekitaran dan fail token, kemudian menyiasat API HTTP Vault untuk menyenaraikan rahsia yang boleh diakses.
Di luar IAM awan, perisian hasad ini melakukan pelbagai fungsi sapuan sistem fail menggunakan lebih 150 corak globIa memburu kunci peribadi SSH, konfigurasi Docker, .env fail, stor kelayakan Git, .npmrc dan .pypirc fail, kelayakan Terraform dan kargo, fail sejarah shell, data dompet mata wang kripto dan direktori konfigurasi untuk aplikasi pemesejan yang digunakan secara meluas seperti Signal, Telegram Desktop, Discord, Slack dan Element. Ia juga menyemak fail konfigurasi VPN daripada perkhidmatan termasuk NordVPN, ProtonVPN, CyberGhost, PIA dan lain-lain, berserta token dan domain untuk pengurus repositori binari seperti JFrog Artifactory.
Pengekstrakan melalui repo GitHub dan komitmen "meow meow meow"
Selepas mengumpul semua rahsia ini, perisian hasad memerlukan tempat untuk menghantarnya. Daripada menggunakan domain arahan dan kawalan tetap yang boleh disekat dengan mudah, penyerang bergantung pada repositori GitHub awam sebagai saluran penapisan , menggabungkan data yang dicuri ke dalam aliran biasa trafik pembangun.
Muatan tersebut mula-mula mencari sejarah komit awam GitHub untuk mesej yang sepadan dengan corak tertentu yang membenamkan token yang disulitkan secara jelas, menggunakan frasa yang memarahi pengguna kerana membatalkannya. Sebaik sahaja komit sedemikian ditemui, perisian hasad akan menyahsulit token yang terbenam dan menggunakan akaun yang berkaitan untuk mencipta repositori baharu di mana data yang dicuri akan disimpan. Tindakan tidak langsung ini bermakna kelayakan yang diambil daripada seorang mangsa disimpan dalam repositori yang dimiliki secara teknikal oleh pengguna GitHub yang lain, menjadikan rangkaian repo yang dikompromi lebih sukar untuk dikesan kembali kepada identiti penyerang tunggal.
Repositori yang baru diwujudkan telah nama-nama aneh yang dijana secara automatik terdiri daripada dua watak daripada siri Projek Touhou dan nombor rawak, menghasilkan kombinasi seperti cirno-marisa-74291 or reimu-kogasa-12048Huraian mereka ditetapkan kepada frasa “Trinitit: Ditaja oleh Pratonton 2 Kesan” yang sama seperti yang dilihat dalam muatan, memberikan satu-satunya penanda yang jelas untuk pemain pertahanan yang cuba mengenal pasti repo ini pada skala besar.
Kelayakan yang dicuri dilakukan sebagai fail JSON yang disulitkan di dalam results/ direktori, menggunakan nama fail yang bermula dengan doubletrinnys- diikuti dengan kaunter dan cap waktu. Setiap fail mengandungi envelope medan yang menyimpan pakej data yang disulitkan dan a key medan yang mengandungi kunci penyulitan itu sendiri, dibungkus lagi menggunakan kunci awam RSA penyerang. Dari pandangan biasa, ini kelihatan seperti gumpalan yang disulitkan sewenang-wenangnya. Hanya seseorang yang mempunyai kunci persendirian yang sepadan boleh membalikkan proses tersebut, jadi walaupun repositori ditemui, rahsia sebenar kekal kabur kepada pihak ketigaMesej commit biasanya pendek dan sembrono, dengan rentetan seperti “meow meow meow” digunakan berulang kali.
Penyebaran seperti cacing ke dalam pakej npm lain dan projek GitHub
Salah satu aspek yang paling membimbangkan kempen Trinitite ialah keupayaannya untuk menggunakan semula token yang dicuri untuk menjejaskan pakej dan repositori tambahan . Daripada mengehadkan dirinya kepada pakej penjana kod Pertanyaan TanStack yang asal, perisian hasad ini bertindak seperti cacing, secara sistematik mencari jalan untuk merebak.
Dengan token npm yang sah di tangan, muatan akan membuat pertanyaan pada API npm untuk menyenaraikan semua token yang berkaitan dengan akaun tersebut, memilih token penerbitan yang paling istimewa. Kemudian, ia melakukan carian untuk setiap pakej yang dimiliki oleh penyelenggara tersebut, memuat turun tarball sedia ada untuk setiap satu dan menyuntik fail pelepasan kotak pasir binding.gyp dan fail muatan utama yang sama ke dalam kandungan pakej. Selepas pengubahsuaian, ia menerbitkan versi baharu kepada npm di bawah nama penyelenggara yang sah, sekali gus mengubah pakej yang dipercayai menjadi vektor jangkitan baharu . Tingkah laku yang serupa dilaksanakan untuk PyPI dan RubyGems melalui titik akhir muat naik masing-masing, dengan semakan sijil TLS dinyahdayakan dalam permintaan keluar untuk mengelakkan masalah penyematan bahagian klien.
Repositori GitHub dilayan dengan cara yang setanding. Apabila perisian hasad memperoleh token GitHub dengan skop yang mencukupi, ia menyenaraikan setiap repositori dan cabang yang boleh diakses, melangkau beberapa cabang automasi yang diketahui seperti yang diawali dengan release/, dependabot/, renovate/ or copilot/Untuk cawangan yang selebihnya, ia memasukkan satu set fail yang dipilih dengan teliti yang berfungsi sebagai pintu belakang dan sebagai cangkuk ke dalam perkakasan pembangunan moden.
Antaranya ialah Kod VS pintu belakang dan fail konfigurasi Claude, Termasuk .vscode/tasks.json, .claude/settings.json dan skrip seperti setup.mjs yang dilaksanakan apabila pembangun membuka projek dalam editor berbantukan AI tertentu. Perisian hasad ini juga mengeluarkan perisian palsu .github/workflows/codeql.yml aliran kerja yang menyamar sebagai imbasan keselamatan sambil menyediakan saluran lain untuk pelaksanaan kod di dalam CI. Fail tambahan disasarkan kepada editor dan alatan lain, seperti Gemini, Cursor dan pelbagai pembantu kod, membantu penyerang mengekalkan kegigihan di mana sahaja pembangun benar-benar bekerja.
Setiap komitmen ini dikarang di bawah github-actions identiti, dengan mesej yang kelihatan seperti penyelenggaraan rutin seperti “kerja rumah: kemas kini kebergantungan” dan treler yang ditandai skip-checks:true untuk terlepas daripada semakan yang diperlukan. Bagi pasukan yang sibuk yang mengimbas log komit sepintas lalu, perubahan ini mudah disalah anggap sebagai kemas kini automasi yang tidak berbahaya.
Petunjuk kompromi untuk pasukan yang menggunakan perkakasan Pertanyaan TanStack
Bagi organisasi yang bergantung pada TanStack Query dan telah mengintegrasikan @7nohe/openapi-react-query-codegen ke dalam aliran kerja mereka, mengenal pasti potensi pendedahan bermula dengan penunjuk versi dan peringkat fail yang kini telah diserlahkan oleh pelbagai sumber. Petunjuk ini boleh membantu menentukan projek mana yang mungkin telah menjalankan kod yang terjejas semasa langkah pemasangan mereka.
Sebarang penggunaan versi @7nohe/openapi-react-query-codegen yang terjejas yang disenaraikan sebelum ini harus dianggap sebagai mencurigakan, terutamanya jika binaan dilakukan pada infrastruktur CI kongsi atau komputer riba pembangun dengan akses kepada kelayakan sensitif. Pasukan keselamatan dinasihatkan untuk mengaudit fail kunci, sejarah package.json dan log binaan untuk mengesahkan sama ada keluaran tersebut pernah ditarik ke dalam persekitaran pengeluaran atau pementasan.
Pada cakera, tanda utama pencerobohan ialah kehadiran fail 3FWCvzduYZg.js pada akar pakej . Penyiasat telah mengkatalogkan beberapa hash SHA‑256 yang dikaitkan dengan binaan skrip yang dikaburkan yang berbeza, semuanya dikaitkan dengan fungsi asas yang sama:
- 8e5d1af68ca340ae0c6e8132cb00c686ec2d60502c1994d94ce353d1472ad5a3
- b49afb7dba04cd99b357ce7c652c823a3707f28e130bd5c6645851a7adc030d6
- 59370c67b54a0ccaedd265e2356f04540b2fba1e1845300ef6de4d5437d99380
- 778d6f0058045d6a2ab9a7e1d3e3be8e7e6b4d9cc217d13949bf1dfbab759a7c
- b24d121667f21f492cb9db34fbfd515d5922a8dd30b9c45215c7220abbb10ca8
- e1f1162ece9a6e6ea21a20399cbf31c563a8149d433a68711f4223870c203d5a
- b6012b2ff87f08f93ee53921c48db907ddbcf5461b03bb988083b01a36886237
- 709af2fdeb50324229e94c44c679a0fab18bd8e17d3864405989c526cbb63ad8
Di samping itu, banyak hos yang dijangkiti mencipta direktori sementara dengan nama yang bermula dengan trinnyyyy- diikuti oleh rentetan pendek aksara abjad angka rawak dalam folder sementara sistem. Walaupun corak ini sahaja tidak membuktikan kompromi, digabungkan dengan fail binding.gyp yang mencurigakan dan salah satu hash muatan yang diketahui, ia meningkatkan kemungkinan malware Trinitite telah dilaksanakan pada sistem tersebut dengan ketara.
Sesetengah vendor keselamatan telah memasukkan penunjuk ini ke dalam suapan pengesanan mereka. Contohnya, platform yang tertumpu pada perkakasan pembangun dan keselamatan rantaian bekalan kini menandakan mana-mana repositori atau projek yang mengimport versi yang terjejas sebagai isu perisian hasad kritikal , selalunya menilainya pada tahap keterukan maksimum untuk mendorong siasatan segera. Pasukan digalakkan untuk menjalankan imbasan semula merentasi organisasi mereka, terutamanya dalam persekitaran di mana TanStack Query menjadi pusat kepada seni bina aplikasi dan alatan penjanaan kod digunakan secara meluas.
Alatan khusus dan utiliti sumber terbuka sedang muncul yang berada di hadapan npm, yarn, pnpm dan pengurus pakej yang berkaitan, menyemak versi pakej terhadap suapan risikan yang dikurasi sebelum pemasangan. Ideanya adalah untuk memintas pakej yang berniat jahat atau mencurigakan, terutamanya yang berkaitan dengan insiden seperti ini, sebelum ia sampai. node_modules, mengurangkan risiko yang boleh didedahkan secara tidak langsung oleh pustaka pembantu yang dikompromi Aplikasi berkuasa Pertanyaan TanStack dan infrastruktur yang berkaitan dengannya.
Bagi pasukan pembangunan, insiden ini menggariskan bagaimana pakej kemudahan yang nampaknya tidak berbahaya—yang hanya menjana cangkuk bertaip untuk Pertanyaan TanStack daripada spesifikasi OpenAPI—boleh menjadi vektor serangan yang kuat apabila saluran paip dan saluran pengedaran CInya disubversifkan. Langkah pertahanan kini perlu melangkaui semakan kebergantungan aplikasi utama untuk memasukkan penjana, CLI dan skrip automasi yang secara senyap membentuk cara kebergantungan tersebut digunakan setiap hari.