Analisis Kerentanan Compiler Solidity dan Strategi Keamanan untuk Pengembang

Analisis Kerentanan Kompilator Solidity dan Strategi Penanganannya

Kompiler adalah salah satu komponen dasar dari sistem komputer modern. Ini adalah program komputer, dengan fungsi utama mengubah kode sumber bahasa pemrograman tingkat tinggi yang mudah dipahami dan ditulis oleh manusia menjadi kode instruksi yang dapat dieksekusi oleh CPU tingkat rendah atau mesin virtual byte.

Kebanyakan pengembang dan ahli keamanan biasanya akan lebih memperhatikan keamanan kode aplikasi program, tetapi mungkin akan mengabaikan masalah keamanan pada compiler itu sendiri. Faktanya, compiler sebagai program komputer juga memiliki celah keamanan, dan celah-celah ini dalam kondisi tertentu dapat membawa risiko keamanan yang serius. Misalnya, saat browser mengompilasi dan menganalisis eksekusi kode JavaScript front-end, mungkin karena celah pada mesin pengurai JavaScript, menyebabkan pengguna yang mengunjungi halaman web berbahaya diserang oleh penyerang untuk mengeksekusi kode jarak jauh, dan akhirnya mengendalikan browser korban bahkan sistem operasinya.

Kompiler Solidity tidak terkecuali, menurut peringatan keamanan dari tim pengembang Solidity, terdapat kerentanan keamanan di beberapa versi yang berbeda dari kompilator Solidity.

Kerentanan Kompiler Solidity

Fungsi compiler Solidity adalah untuk mengubah kode kontrak pintar yang ditulis oleh pengembang menjadi kode instruksi EVM( Ethereum Virtual Machine). Kode instruksi EVM ini dikemas dan diunggah ke Ethereum melalui transaksi, dan akhirnya dieksekusi oleh EVM.

Perlu membedakan antara kerentanan compiler Solidity dan kerentanan EVM itu sendiri. Kerentanan EVM mengacu pada masalah keamanan yang muncul saat mesin virtual menjalankan instruksi. Karena penyerang dapat mengunggah kode sembarangan ke Ethereum, kode ini pada akhirnya akan dijalankan di setiap program klien P2P Ethereum, jika EVM memiliki kerentanan keamanan, itu akan mempengaruhi seluruh jaringan Ethereum, yang dapat menyebabkan penolakan layanan seluruh jaringan (DoS) bahkan dapat sepenuhnya dikendalikan oleh penyerang. Namun, karena desain EVM relatif sederhana, dan kode inti tidak sering diperbarui, kemungkinan masalah di atas terjadi cukup rendah.

Vulnerability pada compiler Solidity merujuk pada masalah yang terjadi saat compiler mengubah Solidity menjadi kode EVM. Berbeda dengan skenario di mana JavaScript dikompilasi dan dijalankan di komputer klien pengguna seperti browser, proses kompilasi Solidity hanya dilakukan di komputer pengembang kontrak pintar, dan tidak dijalankan di Ethereum. Oleh karena itu, kerentanan pada compiler Solidity tidak akan mempengaruhi jaringan Ethereum itu sendiri.

Salah satu bahaya utama dari kerentanan compiler Solidity adalah dapat menyebabkan kode EVM yang dihasilkan tidak sesuai dengan harapan pengembang kontrak pintar. Karena kontrak pintar di Ethereum sering melibatkan aset cryptocurrency pengguna, maka setiap bug kontrak pintar yang disebabkan oleh compiler dapat mengakibatkan kerugian aset pengguna, yang dapat menghasilkan konsekuensi serius.

Pengembang dan auditor kontrak mungkin akan lebih fokus pada masalah implementasi logika kode kontrak, serta masalah keamanan di tingkat Solidity seperti reentrancy dan overflow integer. Namun, untuk menemukan kerentanan pada compiler Solidity, hanya dengan melakukan audit logika sumber kode kontrak akan sulit untuk mengidentifikasinya. Diperlukan analisis bersama antara versi compiler tertentu dan pola kode tertentu untuk menentukan apakah kontrak pintar terpengaruh oleh kerentanan compiler.

Analisis Kerentanan Compiler Solidity dan Tindakan Penanggulangan

Contoh Kerentanan Compiler Solidity

Berikut ini melalui beberapa contoh kasus kerentanan pada compiler Solidity yang nyata, menunjukkan bentuk, penyebab, dan bahaya spesifiknya.

SOL-2016-9 HighOrderByteCleanStorage

Kerentanan ini ada di versi awal compiler Solidity (>=0.1.6 <0.4.4).

Pertimbangkan kode berikut:

solidity kontrak C { uint32 a = 0x1234; uint32 b = 0; fungsi f() publik { a += 1; } function run() public view returns (uint32) { return b; } }

Variabel penyimpanan b tidak mengalami modifikasi apa pun, sehingga fungsi run() seharusnya mengembalikan nilai default 0. Namun, dalam kode yang dihasilkan oleh compiler versi yang rentan, run() akan mengembalikan 1.

Jika tidak memahami kerentanan compiler tersebut, pengembang biasa akan sulit untuk menemukan bug yang ada dalam kode di atas hanya melalui pemeriksaan kode sederhana. Ini hanya contoh sederhana dan tidak akan menyebabkan konsekuensi yang sangat serius. Namun, jika variabel b digunakan untuk verifikasi izin, pencatatan aset, dan tujuan lainnya, ketidaksesuaian dengan yang diharapkan ini dapat menyebabkan masalah yang sangat serius.

Penyebab fenomena aneh ini adalah karena EVM menggunakan mesin virtual berbasis tumpukan, di mana setiap elemen dalam tumpukan berukuran 32 byte ( yaitu ukuran variabel uint256 ). Di sisi lain, setiap slot dalam penyimpanan tingkat bawah juga berukuran 32 byte. Sedangkan di tingkat bahasa Solidity, mendukung berbagai jenis data yang lebih kecil dari 32 byte, seperti uint32, dan compiler perlu melakukan operasi pembersihan yang sesuai pada bagian tinggi saat menangani variabel semacam itu (clean up) untuk memastikan keakuratan data. Dalam situasi di atas, ketika penjumlahan menghasilkan overflow integer, compiler tidak melakukan pembersihan yang tepat pada bagian tinggi dari hasil, yang menyebabkan bit 1 di bagian tinggi ditulis ke dalam penyimpanan, akhirnya menimpa variabel a dan mengubah nilai variabel b menjadi 1.

SOL-2022-4 InlineAssemblyMemorySideEffects

Pertimbangkan kode berikut:

solidity kontrak C { function f() public pure returns (uint) { assembly { mstore(0, 0x42) } uint x; assembly { x := mload(0) } return x; } }

Kerentanan ini ada dalam compiler versi >=0.8.13 <0.8.15. Compiler Solidity tidak hanya menerjemahkan bahasa Solidity ke dalam kode EVM secara sederhana, tetapi juga melakukan analisis alur kontrol dan data yang mendalam, serta menerapkan berbagai proses optimasi kompilasi untuk mengurangi ukuran kode yang dihasilkan dan mengoptimalkan konsumsi gas selama proses eksekusi. Operasi optimasi semacam ini sangat umum dalam compiler berbagai bahasa tingkat tinggi, tetapi karena situasi yang perlu dipertimbangkan sangat kompleks, sangat mudah muncul bug atau kerentanan keamanan.

Kelemahan kode di atas berasal dari jenis operasi optimasi ini. Misalkan ada kode dalam suatu fungsi yang mengubah data di offset memori 0, tetapi tidak ada tempat lain yang menggunakan data tersebut, maka sebenarnya kode yang mengubah memori 0 dapat dihapus langsung, sehingga menghemat gas, tanpa mempengaruhi logika program selanjutnya.

Strategi optimasi ini sendiri tidak ada masalah, tetapi dalam implementasi kode kompilator Solidity yang spesifik, jenis optimasi ini hanya diterapkan pada blok assembly tunggal. Pada kode PoC yang disebutkan di atas, penulisan dan akses memori 0 berada dalam dua blok assembly yang berbeda, sementara kompilator hanya menganalisis dan mengoptimalkan blok assembly yang terpisah. Karena tidak ada operasi pembacaan setelah penulisan memori 0 di blok assembly pertama, maka instruksi penulisan tersebut dianggap berlebih dan akan dihapus, sehingga menghasilkan bug. Dalam versi yang memiliki kerentanan, fungsi f() akan mengembalikan nilai 0, padahal sebenarnya kode di atas seharusnya mengembalikan nilai yang benar yaitu 0x42.

SOL-2022-6 AbiReencodingHeadOverflowWithStaticArrayCleanup

Pertimbangkan kode berikut:

solidity kontrak C { function f(string[1] calldata a) external returns (string memory) { return abi.decode(abi.encode(a), (string)); } }

Kerentanan ini mempengaruhi compiler versi >= 0.5.8 < 0.8.16. Dalam kondisi normal, variabel a yang dikembalikan oleh kode di atas seharusnya adalah "aaaa". Namun, dalam versi yang terpengaruh, akan mengembalikan string kosong "".

Penyebab dari kerentanan ini adalah bahwa Solidity secara keliru melakukan pembersihan pada beberapa data saat melakukan operasi abi.encode pada array tipe calldata, yang mengakibatkan perubahan pada data lain yang bersebelahan, menyebabkan ketidakcocokan data setelah pengkodean dan pengkodean ulang.

Perlu dicatat bahwa Solidity secara implisit akan melakukan abi.encode pada parameter saat melakukan panggilan eksternal dan mengeluarkan acara, sehingga kemungkinan munculnya kode kerentanan di atas akan lebih tinggi dari yang diharapkan.

Analisis Kerentanan Compiler Solidity dan Tindakan Penanganannya

Saran Keamanan

Tim keamanan blockchain Cobo setelah menganalisis model ancaman kerentanan compiler Solidity dan merangkum kerentanan historis, memberikan saran berikut kepada pengembang dan profesional keamanan.

Untuk Pengembang:

  • Gunakan versi baru dari kompiler Solidity. Meskipun versi baru mungkin juga membawa masalah keamanan baru, masalah keamanan yang diketahui biasanya lebih sedikit dibandingkan versi lama.

  • Menyempurnakan kasus pengujian unit. Sebagian besar bug di level compiler dapat menyebabkan hasil eksekusi kode tidak konsisten dengan yang diharapkan. Masalah seperti ini sulit ditemukan melalui tinjauan kode, tetapi sangat mudah terungkap pada tahap pengujian. Oleh karena itu, dengan meningkatkan cakupan kode, masalah seperti ini dapat dihindari sebanyak mungkin.

  • Usahakan untuk menghindari penggunaan assembly inline, dekode dan enkode abi untuk array multidimensi dan struktur kompleks, serta operasi kompleks lainnya. Hindari menggunakan fitur bahasa baru dan fungsi eksperimental secara membabi buta hanya untuk menunjukkan keahlian, kecuali ada kebutuhan yang jelas. Berdasarkan analisis tim keamanan Cobo terhadap kerentanan sejarah Solidity, sebagian besar kerentanan terkait dengan operasi assembly inline, enkoder abi, dan lainnya. Kompiler memang lebih mudah mengalami bug saat menangani fitur bahasa yang kompleks. Di sisi lain, pengembang juga rentan melakukan kesalahan saat menggunakan fitur baru, yang dapat menyebabkan masalah keamanan.

kepada petugas keamanan:

  • Saat melakukan audit keamanan kode Solidity, jangan mengabaikan risiko keamanan yang mungkin diperkenalkan oleh compiler Solidity. Item pemeriksaan yang sesuai dalam Klasifikasi Kelemahan Kontrak Pintar(SWC) adalah SWC-102: Versi Compiler yang Usang.

  • Dalam proses pengembangan internal SDL, mendorong tim pengembang untuk memperbarui versi compiler Solidity, dan dapat mempertimbangkan untuk memperkenalkan pemeriksaan otomatis terhadap versi compiler dalam proses CI/CD.

  • Namun, tidak perlu panik berlebihan tentang kerentanan compiler, sebagian besar kerentanan compiler hanya terpicu dalam pola kode tertentu, dan tidak semua kontrak yang dikompilasi dengan versi compiler yang rentan memiliki risiko keamanan. Dampak keamanan yang sebenarnya perlu dievaluasi secara spesifik berdasarkan situasi proyek.

Sumber Daya Praktis:

  • Pos Peringatan Keamanan yang diterbitkan secara berkala oleh Tim Solidity:

  • Daftar bug yang diperbarui secara berkala di repo resmi Solidity:

  • Daftar bug compiler versi yang berbeda:

  • Kontrak di Etherscan - tanda seru segitiga di pojok kanan atas halaman Kode dapat mengindikasikan adanya kerentanan keamanan pada versi kompiler saat ini.

Ringkasan

Artikel ini dimulai dari konsep dasar compiler, memperkenalkan kerentanan compiler Solidity, dan menganalisis risiko keamanan yang mungkin ditimbulkan dalam lingkungan pengembangan Ethereum yang sebenarnya, akhirnya memberikan beberapa saran keamanan yang praktis untuk pengembang dan personel keamanan.

Analisis Kerentanan Kompiler Solidity dan Tindakan yang Dapat Diambil

ETH2.56%
Lihat Asli
Halaman ini mungkin berisi konten pihak ketiga, yang disediakan untuk tujuan informasi saja (bukan pernyataan/jaminan) dan tidak boleh dianggap sebagai dukungan terhadap pandangannya oleh Gate, atau sebagai nasihat keuangan atau profesional. Lihat Penafian untuk detailnya.
  • Hadiah
  • 5
  • Bagikan
Komentar
0/400
staking_grampsvip
· 15jam yang lalu
Pintu celah banyak, siapa yang berani mengembangkan?
Lihat AsliBalas0
JustHereForMemesvip
· 07-23 05:15
Compiler juga punya masalah besar ya, pergi pergi.
Lihat AsliBalas0
BakedCatFanboyvip
· 07-22 21:56
Jadi semua kesalahan hanya bisa diambil, ya?
Lihat AsliBalas0
OldLeekNewSicklevip
· 07-22 21:56
Suckers tingkat tinggi melihat celah, suckers tingkat bawah mengawasi Buku Pesanan
Lihat AsliBalas0
RektCoastervip
· 07-22 21:52
Kompiler juga mengalami bug? Sungguh membuatku muncul dan meledak di jalan.
Lihat AsliBalas0
Perdagangkan Kripto Di Mana Saja Kapan Saja
qrCode
Pindai untuk mengunduh aplikasi Gate
Komunitas
Bahasa Indonesia
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)