Memindai Kontrak Ethereum Langsung untuk Kesalahan Tidak Terkirim-Kirim. Bagian 2

Kelanjutan artikel "Memindai Kontrak Langsung Ethereum untuk Kesalahan Tidak Terkirim-Kirim". Bagian 1 " .


Hampir setahun yang lalu (ketika Ethereum dalam rilis "perbatasan"), kontrak lotere EtherPot populer [9] juga menderita kesalahan yang sama. Versi BTCRelay sebelumnya juga menunjukkan kesalahan ini [7] . Meskipun bahaya terdeteksi dalam audit keamanan sebelumnya, koreksi yang salah pertama kali diterapkan [8] .


Deteksi kesalahan yang tidak dicentang-kirim pada blockhain langsung


Seberapa umum kesalahan ini? Apakah mereka mendengarkan peringatan? Apakah praktik terbaik diterapkan? Kami menjawab pertanyaan-pertanyaan ini secara empiris dengan menganalisis data dari blok-rantai Ethereum, serta repositori kode Soliditas yang ditemukan di etherscrape.com. Untuk melakukan ini, kami sedang mengembangkan alat analisis program sederhana yang memeriksa kontrak rantai-blok dan menggunakan heuristik untuk memeriksa apakah salah satu metode perlindungan yang paling efektif digunakan. Listing 2 menunjukkan teknik keamanan pertama, seperti yang direkomendasikan dalam dokumentasi Ethereum, yang harus memeriksa nilai balik dari mengirim dan melempar pengecualian. Untuk mendeteksi penggunaan metode ini, kami menggunakan perkiraan kasar: kami hanya melihat apakah nilai balik pengiriman diabaikan atau tidak.

Listing 4 mengilustrasikan teknik keamanan kedua yang direkomendasikan dalam manual UMD, yang secara langsung memeriksa apakah callstack penuh dengan mengirim pesan pengujian. Untuk menemukan teknik ini, kami kembali menggunakan perkiraan kasar: kami hanya memeriksa untuk melihat apakah pesan sedang dikirim selain perintah kirim .

Jika tidak ada indikator heuristik ini hadir, kami menyimpulkan bahwa tidak ada satu pun rekomendasi praktik terbaik yang diikuti. Kami menerapkan heuristik ini menggunakan pencocokan pola sederhana dengan bytecode EVM yang dikompilasi. Rincian lebih lanjut tentang bagaimana kami melakukan ini dapat ditemukan di Lampiran [12] .


Berapa banyak kontrak yang rentan?


Mari kita mulai dengan memeriksa heuristik dalam repositori Etherscrape dari kode sumber Solidity. Pada 20 Maret 2016, relay Etherscrape berisi 361 program kontrak Soliditas, 56 di antaranya berisi pernyataan kirim. Dari program kontrak ini, kami mengasumsikan bahwa sebagian besar (setidaknya 36 dari 56) tidak menggunakan metode pemrograman defensif.

Sekalipun kontrak tidak menggunakan teknologi perlindungan apa pun, kontrak mungkin atau mungkin tidak memiliki kerentanan nyata. Kami secara manual memeriksa kontrak Soliditas untuk mengonfirmasi kerentanan. Untuk tujuan kami, kami menganggap kontrak rentan jika keadaannya dapat berubah meskipun perintah kirim tidak berfungsi (jadi kami akan melihat kode rentan di Listing 5). Kami mengkonfirmasi bahwa sebagian besar kerentanan ada, 32 dari 36 kontrak ini.


Demikian juga, heuristik kami tidak menjamin aplikasi pemrograman defensif yang benar. Ambil contoh, WeiFund, crowdfunding open-source DApp yang terdesentralisasi. Kontrak ini memiliki dua fungsi: pengembalian uang () dan pembayaran () , yang menipu heuristik kami. Berikut ini adalah kutipan dari pengembalian dana .


function refund(uint _campaignID, uint contributionID) public { ... receiver.send(donation.amountContributed); donation.refunded = true; ... if(c.config != address(0)) WeiFundConfig(c.config).refund(_campaignID, donation.contributor, donation.amountContributed); } 

Dalam kode ini, pesan dikirim ke WeiFundConfig (c.config) untuk meminta metode pengembalian dana, tetapi hanya dalam kondisi tertentu. Jika c.config adalah nilai nol, maka kontrak tersebut benar-benar rentan terhadap serangan callstack. Saat memeriksa *, tidak ada program Solidity yang lulus pengujian heuristik kami yang benar-benar menerapkan praktik pengujian callstack terbaik yang direkomendasikan secara langsung. *

Kemudian kita mengalihkan perhatian kita ke kontrak yang dirancang pada Ethereum block-chain yang masih hidup. Kami melihat gambar tanggal 20 Maret 2016 (waktu: 1184243). Cuplikan ini berisi total 13645 rantai blok, yang tampaknya dihasilkan oleh kompiler Soliditas, di mana hanya 1.618 (11,8%) termasuk perintah kirim .

Dari jumlah tersebut, sebagian besar tampaknya tidak menggunakan teknik pemrograman defensif.


Bagaimana dengan masalah balapan rekursif di TheDAO? Kontrak pintar yang paling menarik saat ini, TheDAO [11] , menderita kesalahan yang benar-benar terpisah, yaitu tidak aman untuk digunakan kembali [13] . Ini adalah jenis pemrograman lain yang tidak terhubung (terhubung, tetapi berbeda), yang juga diharapkan dalam pemeriksaan keamanan sebelumnya [6] , tetapi, seperti sebelumnya, ada kemungkinan banyak kontrak tidak aman saat ini. Pekerjaan di masa depan adalah membuat alat yang juga bisa mendeteksi kesalahan seperti itu.


Di mana semuanya salah?


Kami tidak berharap pemrograman pada kontrak pintar menjadi sangat sederhana, setidaknya untuk saat ini. Namun, mengejutkan bahwa bentuk kesalahan khusus ini begitu luas, terlepas dari kenyataan bahwa itu telah dideskripsikan sejak lama selama pengembangan ekosistem Ethereum.

Laporan 2015 [6] membuat rekomendasi ini kepada pengembang Ethereum: "

Saat ini, contoh pemrograman yang disajikan dalam dokumentasi tidak cukup untuk menyebarkan praktik terbaik untuk menulis kontrak aman dan menyelesaikan masalah mekanisme gas. Tutorial pengantar C ++ sering dilewati
memeriksa kesalahan untuk keterbacaan, yang menyebabkan banyak kesalahan keamanan. Contoh Ethereum harus mengajarkan kebiasaan terbaik. Rekomendasi: Berikan lebih banyak lagi contoh pemrograman kontrak keamanan yang cermat. "

Kami hanya tahu satu jawaban resmi untuk pertanyaan ini, yaitu menambahkan peringatan ke dokumentasi Solidity resmi yang disebutkan sebelumnya [3], diulangi di bawah ini: "Ada beberapa bahaya saat menggunakan kirim : Transmisi gagal jika kedalaman tumpukan panggilan adalah 1024 (ini selalu dapat dipanggil oleh penelepon), dan juga gagal jika penerima kehabisan bensin, sehingga untuk memastikan siaran yang aman, selalu periksa nilai balik pengiriman atau bahkan lebih baik: gunakan pola di mana penerima menarik uang. "


Kami percaya bahwa pengamatan ini tidak cukup untuk mendokumentasikan masalah. Ini hanya menawarkan mitigasi yang tidak lengkap dan hanya menjelaskan satu versi dari bahaya, berpotensi menyesatkan pembaca tentang tingkatannya.


  • Perbarui:
    Ketidakcukupan dokumentasi Soliditas juga diilustrasikan secara rinci oleh Peter Wesenes. [16]


Selain itu, peringatan itu tampaknya sering diabaikan. Oleh karena itu, kami percaya bahwa tindakan pencegahan tambahan diperlukan.



Bagaimana Etherscrape dapat membantu?


Kami percaya bahwa menggunakan alat analisis statis, bahkan yang kasar, seperti yang dijelaskan dalam posting ini, dapat membantu meningkatkan kualitas kontrak pintar. Di Etherscrape, kami mengintegrasikan alat analisis seperti ini ke dalam layanan web publik kami, dan kami menambahkan tautan ke halaman alat kapan dia akan siap. Ini akan membuatnya lebih mudah untuk melihat kode kontrak pintar dengan menyoroti tempat-tempat di mana kesalahan dapat terjadi. Kami berasumsi bahwa pengguna kontrak pintar semacam itu (misalnya, calon investor di TheDAO atau penawarannya) dapat dengan mudah menggunakan alat seperti cek kewarasan sebelum menyetor uang mereka. Bahkan investor non-teknis dapat meminta pertanggungjawaban pengembang untuk menjelaskan bagaimana mereka bereaksi terhadap masalah yang dicatat dalam kode.

Etherscrape juga membantu dengan menganalisis blok-publik dan mengendalikan prevalensi kesalahan ini, yang dapat membantu dalam memutuskan, misalnya, berapa banyak uang yang harus dialokasikan untuk penelitian dan pengembangan alat analisis statis. Selain itu, kompiler seperti solc dapat mengintegrasikan analisis tersebut, memberikan peringatan kepada programmer ketika kesalahan tampaknya terjadi.


Bacaan yang Disarankan



Source: https://habr.com/ru/post/id430684/


All Articles