halaman depan artikel

Analisis Daftar Periksa Solodit: Penolakan Serangan Layanan Bagian 2

2025-04-15

Analisis Daftar Periksa Solodit (2): Penolakan Serangan Layanan Bagian 2

Pelajari cara mencegah serangan penolakan layanan (DOS) dalam kontrak pintar dengan memastikan antrian aman, menangani token desimal rendah, dan mengelola panggilan eksternal dengan aman.

Selamat datang kembali ke seri Resolusi Daftar Periksa Solodit . Kami akan terus mengeksplorasi daftar periksa audit kontrak pintar Solodit, dengan fokus pada strategi praktis untuk menulis kontrak pintar yang aman dan tangguh.

Daftar periksa ini membantu Anda mengidentifikasi potensi kerentanan dan menerapkan langkah -langkah keamanan proaktif. Pada bagian sebelumnya " Resolusi Daftar Periksa Solodit (1) ", kami memeriksa tiga daftar periksa ( pola ekstraksi, jumlah transaksi minimum, dan daftar hitam) yang terkait dengan serangan penolakan layanan (DOS) dan memberikan solusi untuk pengembang. Jika Anda belum membacanya, saya sarankan memeriksa artikel sebelum melanjutkan.

Dalam artikel ini, kita akan membahas tiga item lain dalam daftar periksa, dengan fokus lagi pada serangan DOS. Kami akan menyelami kerentanan penanganan antrian , tantangan yang ditimbulkan oleh token desimal rendah , dan pentingnya menangani panggilan kontrak eksternal dengan aman .

Untuk pengalaman terbaik, buka tag daftar periksa solodit untuk referensi.

Tinjauan singkat

Inilah yang akan kita bahas hari ini:

  • Sol-am-dosa-4: Memblokir penanganan antrian : Masalah ini terjadi ketika penyerang memanipulasi antrian untuk menjeda atau mengganggu operasinya, menghasilkan DOS. Kita akan melihat bagaimana penyerang dapat menghancurkan antrian pemrosesan.

  • Sol-am-dosa-5: Token desimal rendah : masalah yang terjadi ketika berhadapan dengan token dengan tempat desimal rendah. Perhitungan, terutama pembagian, dapat dipotong menjadi nol, menghasilkan perilaku yang tidak terduga dan berbahaya. Token presisi rendah ini dapat menyebabkan masalah dengan divisi integer, sehingga mengganggu fungsi utama.

  • Sol-am-dosa-6: Panggilan eksternal yang tidak aman : Kami akan mengeksplorasi cara mengandalkan kontrak eksternal tanpa penanganan kesalahan yang tepat untuk menciptakan kerentanan. Ketika kegagalan panggilan eksternal tidak ditangani dengan benar, itu dapat menyebabkan seluruh kontrak mundur .

Serangan dunia nyata membuktikan potensi kerusakan yang dapat ditimbulkan oleh kerentanan ini. Proyek ini menderita kerugian besar karena kelalaian yang tampaknya kecil.

Daftar periksa solodit didasarkan pada temuan audit, laporan karunia kerentanan, dan peristiwa dunia nyata. Dengan mempelajari daftar periksa ini, Anda dapat belajar dari kesalahan masa lalu dan meningkatkan keamanan kode Anda .

Sekarang, mari kita lihat setiap item cek satu per satu melalui kode sampel. Contoh -contoh ini telah disederhanakan untuk menyoroti kerentanan inti.

Sol-am-dosa-4: Dapatkah penyerang memblokir atau mencegah pemrosesan antrian menyebabkan pemadaman layanan?

Masalah : Jika kontrak pintar Anda tergantung pada antrian untuk pemrosesan tugas, penyerang dapat memanipulasi keadaan tertentu dalam antrian untuk mencegah pemrosesan yang benar.

Pertanyaan Daftar Periksa : "Dapatkah penyerang memblokir atau mencegah pemrosesan antrian menyebabkan pemadaman layanan?"

Solusi : Mekanisme penanganan antrian Anda membutuhkan penanganan kesalahan yang kuat dan mekanisme fallback untuk memastikan bahwa masalah dapat terus diproses bahkan jika itu terjadi.

Contoh :

Pertimbangkan contoh mengekstraksi antrian:

  1. Pengguna meminta ekstraksi, dan beberapa bendera menunjukkan bahwa permintaan tersebut aktif.

  2. Penyerang dapat menggunakan fungsi resetUserStatus setelah ekstraksi diaktifkan untuk mencegah operasi pengguna lain yang sama.

 // 易受攻击的函数:可以被利用function resetUserStatus() external { // 任何人在仍然处于队列中的情况下都可以重置他们的状态withdrawalRequested[msg.sender] = false; // 注意:用户没有被移出队列! } // 处理队列中的下一次提取function processNextWithdrawal() external { require(withdrawalQueue.length > currentIndex, "没有可处理的提取"); // 获取下一次提取Withdrawal memory withdrawal = withdrawalQueue[currentIndex]; // 可被攻击者利用:此检查可能会被重置状态所攻击require(withdrawalRequested[withdrawal.user], "提取请求不再有效"); // 处理提取uint256 amount = withdrawal.amount; require(balances[withdrawal.user] >= amount, "余额不足"); // 更新余额balances[withdrawal.user] -= amount; // 重置提取请求withdrawalRequested[withdrawal.user] = false; // 发送资金(bool success, ) = payable(withdrawal.user).call{value:amount}(""); require(success, "资金发送失败"); // 移动到队列中的下一个currentIndex++; }

Untuk memanfaatkan ini, penyerang dapat melakukan hal berikut:

  1. Memulai permintaan pengambilan.
  2. Hubungi fungsi resetUserStatus .
  3. Fungsi processNextWithdrawal akan mundur, menyebabkan serangan DOS terus menerus.

Pemulihan :

  • Batasi izin untuk memodifikasi status withdrawalRequested ke administrator.
  • Pastikan untuk memverifikasi cek untuk menghindari transaksi nilai nol.
  • Menerapkan fungsi fallback untuk menangani kesalahan yang tidak terduga.

Sol-am-dosa-5: Akankah token desimal rendah mengarah ke DOS?

Masalah : Token dengan tempat desimal rendah dapat menyebabkan masalah pembagian bilangan bulat, sehingga membulatkan ke nol .

Bayangkan kontrak streaming token mengalokasikan token selama periode waktu tertentu. Jika tokensPerSecond putaran ke nol karena divisi integer dengan token desimal rendah, fungsi alokasi akan diblokir. Pertanyaan Daftar Periksa : "Apakah token desimal rendah mengarah ke DOS?" Solusi : Menerapkan logika untuk menangani titik desimal rendah untuk mencegah gangguan proses perdagangan karena kesalahan pembulatan. Contoh :

Pertimbangkan kontrak TokenStream yang secara teratur mengalirkan sejumlah token ke pengguna, di mana:

  1. total_tokens perlu ditransfer ke kontrak
  2. token_per_second dapat dibulatkan ke nol karena kami menggunakan token dengan titik desimal 1
  3. Fungsi distributeTokens akan berputar kembali
 contract TokenStream { IERC20 public token; uint256 public streamDuration; uint256 public tokensPerSecond; constructor(IERC20 _token, uint256 _streamDuration, uint256 _tokensPerSecond) { token = _token; streamDuration = _streamDuration; tokensPerSecond = _tokensPerSecond; } function distributeTokens(address recipient) external { uint256 balance = token.balanceOf(address(this)); uint256 amount = tokensPerSecond * streamDuration; uint256 tokensToSend = amount > balance ? balance : amount; require(tokensToSend > 0, "没有足够的代币进行流送"); token.transfer(recipient, tokensToSend); } } contract LowDecimalToken is ERC20 { constructor() ERC20("LowDecimalToken", "LDT") { _mint(msg.sender, 100000 * (10 ** decimals())); } function decimals() public view virtual override returns (uint8) { return 1; // 模拟小数点为低的代币} }

Dalam hal ini, tes testDOSWithLowDecimalTokens di TokenStreamTest akan digulung kembali.

Obat : Pastikan kontrak menangani token desimal rendah dengan benar, mengurangi masalah yang disebabkan oleh bilangan bulat pembulatan selama proses perhitungan dengan menskalakan rumus matematika .

Sol-am-dosa-6: Apakah protokol dengan aman menangani interaksi kontrak eksternal?

Masalah : Banyak kontrak pintar bergantung pada kontrak eksternal untuk berinteraksi. Perilaku kontrak eksternal yang tidak terduga dapat menyebabkan seluruh sistem mundur . Kegagalan untuk menangani kesalahan eksternal ini dapat menyebabkan kerentanan DOS.

Pertanyaan Daftar Periksa : "Apakah protokol menangani interaksi kontrak eksternal dengan aman?"

Solusi : Pastikan penanganan kesalahan yang kuat untuk interaksi kontrak eksternal untuk melindungi integritas protokol terlepas dari kinerja kontrak eksternal.

Contoh : Pertimbangkan kontrak yang berinteraksi dengan sumber data harga rantai eksternal. Jika Anda tidak menggunakan Coba/Catch untuk penanganan kesalahan yang tepat, setiap rollback dari sumber data eksternal akan menyebar ke superior dan menyebabkan kontrak menjadi rollback.

  1. Fungsi getPrice mengambil data harga.
  2. Ketika rantai eksternal Oracle gagal, seluruh kode akan digulung kembali.
  3. Fungsi calculateSomethingImportant tergantung pada getPrice dan juga akan mundur.
 contract PriceDependentContract { AggregatorV3Interface public priceFeed; constructor(address _priceFeed) { priceFeed = AggregatorV3Interface(_priceFeed); } // 易受攻击的函数,在没有处理可能的Chainlink 回滚的情况下获取价格function getPrice() public view returns (uint256) { (, int256 price, , , ) = priceFeed.latestRoundData(); // 易受攻击的行:没有错误处理require(price > 0, "价格必须为正"); return uint256(price); } function calculateSomethingImportant() public view returns (uint256) { uint256 price = getPrice(); // ... 使用价格的一些重要计算return price * 2; }

Obat : Bungkus panggilan kontrak eksternal dalam blok coba/tangkap untuk menangani kesalahan rollback dan mengimplementasikan nilai rollback atau cache.

CATATAN : Ada kasus tepi di mana kontrak eksternal dengan sengaja mengkonsumsi gas , yang juga dapat gagal dalam blok tangkapan! Kami akan membahas ini nanti.

sebagai kesimpulan

Kami mengeksplorasi tiga pemeriksaan utama yang dirancang untuk meningkatkan kemampuan kontrak pintar Anda untuk menolak serangan DOS: antrian penanganan kerentanan , tantangan yang terkait dengan token desimal yang rendah , dan pentingnya menangani interaksi kontrak eksternal dengan aman .

Ingatlah bahwa contoh -contoh yang diberikan dimaksudkan untuk menggambarkan kerentanan inti. Sangat penting untuk memahami prinsip -prinsip dasar dan menyesuaikan konsep -konsep ini dengan kasus penggunaan spesifik Anda.

Dengan menerapkan saran -saran ini, Anda dapat secara signifikan meningkatkan keamanan dan ketahanan kontrak pintar Anda.

Tetap disini untuk bagian selanjutnya dari Seri Resolusi Daftar Periksa Solodit.

  • Tautan asli: cyfrin.io/blog/solodit-c ...
  • Komunitas Denglian AI Asisten menerjemahkan artikel bahasa Inggris yang sangat baik untuk semua orang. Jika ada area di mana terjemahannya tidak dapat dimengerti, tolong maafkan saya ~

Pembaruan terkini

Artikel populer

Rekomendasi permainan

Rekomendasi perangkat lunak