Solidity

Solidity 與 Rust 的安全性

  • April 13, 2022

我最近開始學習Solidity,我對安全方面很感興趣。今天,我遇到了一篇非常有趣的部落格文章,討論Rust. 在我的理解水平上,這裡評論的其他漏洞可能不是 和 的情況first,這給我的印像比 .具有更強的安全性。如果我的想法沒有錯,我希望能聽取其他專家的意見。請在文章中公開討論以下項目,如果有更多的安全考慮,也請提出建議,一般情況下,以. 謝謝。third``Solidity``Solidity``Rust``Solidity

1.缺少所有權檢查

智能合約通常包含只有特定賬戶才能訪問的特權功能。如果是這種情況,則智能合約應在執行此特權功能之前驗證帳戶是否可信。

所有 Solana 賬戶都歸智能合約所有——這條規則也不例外。只有合約才能修改賬戶數據。實施必要的授權控制是智能合約開發人員的任務,包括驗證交易發送者的數字簽名。

Solana 中的帳戶元資料結構包括所有者欄位,該欄位指示與該帳戶所有者關聯的公鑰。要驗證一個帳戶是否可信,應根據預期值檢查儲存在其所有者欄位中的公鑰。

一些 Solana 智能合約使用配置或其他實用程序帳戶來儲存可信數據或管理員帳戶的公鑰。這些帳戶必須由執行智能合約並執行某些操作的使用者提供。

但是,如果合約不驗證公用事業帳戶的所有者,則它可能容易受到利用。如果帳戶所有者沒有被驗證為預期的那樣,攻擊者可以使用虛假配置帳戶繞過訪問控制,並欺騙智能合約執行特權操作。

Solana 智能合約不應天生信任某些賬戶,而是應驗證它們是否為合約所有者所有。

2. 缺乏簽名驗證

對於受限功能,檢查呼叫帳戶的公鑰是否與授權使用者的公鑰匹配是重要的第一步。但是,從技術上講,一個帳戶可以將其數據設置為任何它想要的;這只是數據。

當帳戶使用與該公鑰關聯的私鑰簽署操作時,就會發生驗證。如果智能合約無法檢查操作是否已簽名,那麼只要他們的帳戶包含正確的公鑰,任何人都可以呼叫該指令。

Solana 智能合約應在執行特權功能之前驗證操作是否使用適當的私鑰簽名。

3. 整數上溢和下溢

Rust(和其他程式語言)將值儲存在固定大小的變數中。這意味著這些變數只能保持一定範圍的值。如果操作導致的值超出此範圍,則會創建整數上溢或下溢。

在調試模式下,Rust 將檢查上溢和下溢,但在發布模式(由 Solana BPF 工具鏈使用)中並非如此。如果一個值超出了變數可以支持的值範圍,它將環繞。

攻擊者可以利用這一事實來逃避價值轉移的驗證。如果程序檢查 a + b < c 並且 a 和 b 在傳輸中沒有加在一起,那麼攻擊者可以選擇 a 和 b 的值來溢出檢查。稍後,當發生傳輸時,只使用一個值,這意味著它不會溢出,大量的值將被發送到指定的地址。

整數上溢和下溢通常是由不安全的數學和變數類型之間的不安全強制轉換導致的。如果它使用算術和強制轉換操作的檢查版本,如果發生上溢/下溢,智能合約將拋出錯誤,導致交易被取消。

4. 未能驗證外部程序

智能合約旨在相互互動並從外部程序呼叫函式。Solana 的設計模式規定,要在函式中呼叫的程序應作為參數傳遞給該函式。

函式參數可能在使用者的控制之下,這意味著攻擊者可以提供惡意輸入。通過將相似程序作為參數傳遞給易受攻擊的函式,攻擊者可以說服智能合約執行該程序(有時甚至假設呼叫程序的身份)而不是他們想要的程序。

就像根據公鑰驗證賬戶一樣,智能合約應該根據公鑰驗證他們呼叫的程序。這驗證了該程序是智能合約打算呼叫的程序。

5. 缺少賬戶結構驗證

Solana 智能合約可以為不同的目的定義多個不同的賬戶。這些攻擊可以具有不同的結構並包含不同類型的數據。

賬戶數據以字節數組的形式傳遞給 Solana 智能合約函式,然後接收方根據預期賬戶類型的結構對其進行反序列化。這為惡意使用者創建了一種類型的帳戶並將其作為另一種類型帳戶的實例傳遞給智能合約功能的利用創造了機會。

如果賬戶的所有權檢查是由合約自己的功能之一創建的,則該賬戶的所有權檢查將通過所有權檢查。但是,與該帳戶關聯的數據將根據感知的帳戶類型進行解釋,這可能允許攻擊者設置某些值並通過檢查。

這種攻擊利用了一種帳戶可以替換另一種帳戶的事實。如果一個帳戶的數據以該類型帳戶唯一的標識符開頭,並且該值由使用該帳戶的函式檢查,則該攻擊是不可能的。

參考

[1] Rob Behnke, 04.11.2022, https://halborn.com/how-to-hack-solana-smart-contracts-programs/

PS 我相信這篇文章對於我們公開討論來說是非常相關的,即使它甚至不包含一行程式碼。

這個問題的問題在於,Rust 在這個乙太坊開發者社區中很少使用。我對 Rust 了解不多,但我所知道的是,乙太坊智能合約比 Solana 上的合約更容易受到攻擊。如果您知道自己在做什麼,並且閱讀了您正在使用的包和導入契約的文件,那麼 Solidity 是非常安全的。大多數導入的智能合約向另一個智能合約添加功能,例如允許您創建多重簽名錢包的智能合約,都需要進行審查。我不知道你是否已經閱讀過這個“攻擊”,但如果你沒有,你應該閱讀。HackerNoon MutiSig 錢包凍結

如果您確切地知道自己在做什麼,那麼使用 Solidity 就可以了。在閱讀了您發布的內容後,似乎 Rust 允許更多的偶然錯誤。與乙太坊相比,沒有多少人知道 Rust,而像 Solana 這樣主要使用 Rust 的網路沒有像乙太坊網路那麼多的使用者,這使得它不太成為目標。Solidity > Rust = 技術安全。Rust > Solidity = 不太可能被攻擊。

引用自:https://ethereum.stackexchange.com/questions/126078