輸入驗證(Input Validation)是確保智能合約僅處理有效且預期的資料。當智能合約未對輸入資料進行驗證時,可能會暴露於多種安全風險,例如邏輯操控、未授權存取或意外行為。如果合約假設用戶輸入的資料總是有效而未進行檢查,攻擊者可能利用這一點輸入惡意資料,從而危害合約的安全性和可靠性。
範例(存在漏洞的合約)
以下是一個缺乏輸入驗證的智能合約範例:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Solidity_LackOfInputValidation {
mapping(address => uint256) public balances;
function setBalance(address user, uint256 amount) public {
// The function allows anyone to set arbitrary balances for any user without validation.
balances[user] = amount;
}
}
漏洞分析:
setBalance
函數:該函數允許任何人為任何地址(user
)設置任意的餘額(amount
),且未對輸入進行任何驗證。- 問題:
- 沒有檢查
user
是否為有效地址(例如,是否為零地址)。 - 沒有限制誰可以調用該函數,任何人都能修改任何地址的餘額。
- 沒有對
amount
進行範圍或有效性檢查,可能導致不合理的餘額值。
- 沒有檢查
這使得攻擊者可以輕易操控合約狀態,例如將自己的餘額設置為任意大值,或將其他用戶的餘額清零。
影響
缺乏輸入驗證可能導致以下嚴重後果:
- 資金損失:攻擊者可通過操控輸入來竊取資金或代幣。
- 狀態變數損壞:不當輸入可能導致合約狀態變數(如餘額)被錯誤修改,造成不可靠或不安全的行為。
- 未授權操作:攻擊者可能執行未經授權的交易或操作,影響用戶及整個系統的運作。
修復方法
為避免缺乏輸入驗證的問題,開發者應採取以下措施:
- 確保輸入符合預期類型:檢查輸入資料是否為正確的資料類型(例如,地址、整數等)。
- 驗證輸入範圍:確保輸入值在可接受的範圍內(例如,金額必須為正數)。
- 限制函數訪問權限:確保只有授權的實體(如合約擁有者)可以調用特定功能。
- 檢查輸入結構:驗證輸入的格式,例如地址是否有效,或字串長度是否符合要求。
- 錯誤處理:當輸入無效時,立即停止執行並返回清晰的錯誤訊息。
修復後的範例合約
以下是修復了輸入驗證問題的合約範例:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract LackOfInputValidation {
mapping(address => uint256) public balances;
address public owner;
constructor() {
owner = msg.sender;
}
modifier onlyOwner() {
require(msg.sender == owner, "Caller is not authorized");
_;
}
function setBalance(address user, uint256 amount) public onlyOwner {
require(user != address(0), "Invalid address");
balances[user] = amount;
}
}
修復內容:
1.新增擁有者控制:
- 通過
constructor
設置合約擁有者(owner
),並使用onlyOwner
修飾符限制setBalance
函數僅能由擁有者調用。只有合約擁有者可以修改餘額。
新增程式碼: 構造函數,設置合約擁有者
constructor() {
owner = msg.sender;
}
新增程式碼:僅限擁有者調用的修飾符
modifier onlyOwner() {
require(msg.sender == owner, "Caller is not authorized");
_;
}
2.驗證地址有效性:
- 在
setBalance
函數中,新增了對user
地址的檢查,確保它不是零地址(address(0)
)。
新增程式碼:require(user != address(0), "Invalid address");
總結
缺乏輸入驗證是智能合約中常見的安全漏洞,可能導致資金損失、狀態損壞或未授權操作。透過對輸入資料進行嚴格的類型、範圍、格式和權限驗證,並在無效輸入時提供明確的錯誤訊息,開發者可以顯著提高合約的安全性和可靠性。修復後的合約展示了如何通過權限控制和輸入檢查來解決這些問題。