Lompat ke konten

Risiko penyimpanan delegatecall

Delegatecall menjalankan kode kontrak lain terhadap penyimpanan pemanggil. Pelajari bagaimana benturan penyimpanan, wewenang pemutakhiran, dan target yang tidak tepercaya dapat membahayakan proxy atau dompet pintar.

Diperbarui

Hanya untuk tujuan edukasi; bukan nasihat investasi. Investasi dapat mengakibatkan kerugian.

Jawaban langsung

delegatecall menjalankan kode dari kontrak target dalam konteks kontrak pemanggil. Pemanggil mempertahankan penyimpanan, saldo, dan address(this) miliknya sendiri, sedangkan msg.sender dan msg.value mempertahankan nilai dari panggilan awal.

Perilaku ini memungkinkan adanya proxy, pustaka, dan modul dompet pintar, tetapi juga memberikan wewenang efektif milik pemanggil kepada kode yang didelegasikan. Penulisan penyimpanan, transfer aset, pemberian persetujuan, atau panggilan eksternal dilakukan sebagai pemanggil, bukan sebagai target yang menyediakan kode tersebut.

Perlakukan setiap target delegatecall yang dapat dijangkau sebagai kode dengan hak istimewa. Keamanannya bergantung pada aturan pemilihan target, tata letak penyimpanan yang kompatibel, status inisialisasi, kontrol pemutakhiran, dan implementasi persis yang aktif untuk transaksi tersebut.

Cara kerjanya

Dalam panggilan eksternal biasa, kontrak yang dipanggil membaca dan menulis penyimpanannya sendiri. Dengan delegatecall, bytecode target berjalan terhadap penyimpanan pemanggil: instruksi SSTORE mengubah slot milik pemanggil. Nama variabel target tidak berpengaruh saat runtime; yang berpengaruh hanyalah posisi slot yang dihitung.

Hal tersebut menciptakan empat batas yang perlu diaudit:

  • Kontrol target: tentukan apakah alamat tujuan bersifat tetap, dipilih oleh pengguna, ditentukan melalui registri, atau dapat diubah oleh administrator.
  • Kompatibilitas penyimpanan: bandingkan urutan dan jenis variabel, pewarisan, celah penyimpanan, serta slot bernama atau terstandardisasi di setiap versi implementasi.
  • Inisialisasi dan otorisasi: pastikan initializer tidak dapat dijalankan ulang dan fungsi pemutakhiran atau pengelolaan modul memberlakukan pemanggil serta penundaan tata kelola yang semestinya.
  • Penanganan nilai kembalian: pastikan kegagalan diteruskan dan data kembalian didekode sebagai jenis yang diharapkan; panggilan tingkat rendah tidak menyediakan pemeriksaan jenis kontrak yang biasanya dilakukan Solidity.

ERC-1967 mengurangi benturan proxy dengan menempatkan alamat implementasi, beacon, dan administrator dalam slot terstandardisasi di luar alokasi normal compiler. Standar ini tidak membuktikan bahwa implementasi aman atau bahwa pemutakhiran yang sah tidak berbahaya.

Contoh

Misalkan sebuah dompet menyimpan owner dalam slot 0. Sebuah plugin yang dikompilasi dengan counter dalam slot 0 menaikkan penghitung tersebut ketika dompet mengaksesnya melalui delegatecall.

Penulisan itu mengubah nilai owner dompet karena penyimpanan tersebut milik dompet. Jika nilai yang dihasilkan mengodekan alamat yang dikendalikan penyerang, pemeriksaan otorisasi berikutnya dapat mengenali penyerang sebagai pemilik meskipun plugin tersebut tidak pernah memegang aset dompet.

Tanda terima yang berhasil tidak membedakan perubahan status yang dimaksudkan dari perubahan yang berbahaya. Karena itu, simulasi transaksi perlu memeriksa perbedaan penyimpanan, perubahan aset dan persetujuan, peristiwa yang dipancarkan, serta panggilan berikutnya terhadap alamat proxy dan implementasi yang tepat.

Risiko

  • Eksekusi target arbitrer: target yang dikendalikan pengguna atau divalidasi secara lemah dapat menjalankan kode berbahaya dengan izin pemanggil.
  • Benturan penyimpanan: implementasi dapat menimpa kepemilikan, saldo, status jeda, atau bahkan slot yang memilih implementasi berikutnya.
  • Pemutakhiran tidak aman: administrator atau proses tata kelola yang disusupi dapat mengganti kode yang sebelumnya telah ditinjau setelah pengguna menyetorkan aset atau memberikan persetujuan.
  • Kegagalan inisialisasi: proxy atau implementasi yang belum diinisialisasi dapat memungkinkan akun lain mengambil alih peran dengan hak istimewa atau mengonfigurasi dependensi berbahaya.
  • Pemeriksaan menyesatkan: hanya memverifikasi sumber proxy, implementasi saat ini, atau antarmuka dapat melewatkan beacon, pemutakhiran yang tertunda, registri modul, atau jalur eksekusi alternatif.

Sebelum menandatangani, tentukan implementasi pada blok terbaru, verifikasi siapa yang dapat mengubahnya dan dengan penundaan seperti apa, periksa bytecode terverifikasi dan tata letak penyimpanan target, simulasikan seluruh calldata, lalu bandingkan penyimpanan sensitif dan persetujuan token sebelum serta sesudah eksekusi. Untuk dompet pintar, tinjau juga cara modul diaktifkan, dinonaktifkan, dan diizinkan memilih target.

Kesalahpahaman umum

  • “Target tidak dapat menyentuh aset pemanggil.” Kode yang didelegasikan berjalan sebagai pemanggil dan dapat memanggil kontrak eksternal, mentransfer aset, atau membuat persetujuan jika pemanggil memiliki kemampuan tersebut.
  • “Nama variabel yang sama mencegah benturan.” EVM menggunakan slot penyimpanan, bukan nama dalam kode sumber. Urutan tata letak, pewarisan, dan jenis harus tetap kompatibel.
  • “Kode proxy yang terverifikasi berarti sistemnya terverifikasi.” Implementasi aktif, beacon, administrator pemutakhiran, status inisialisasi, dan izin modul merupakan bagian terpisah dari batas kepercayaan.

Topik terkait

Sumber

Navigasi

Cari di wiki...