SC Lack of Input Validation

輸入驗證(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 進行範圍或有效性檢查,可能導致不合理的餘額值。

這使得攻擊者可以輕易操控合約狀態,例如將自己的餘額設置為任意大值,或將其他用戶的餘額清零。

影響

缺乏輸入驗證可能導致以下嚴重後果:

  1. 資金損失:攻擊者可通過操控輸入來竊取資金或代幣。
  2. 狀態變數損壞:不當輸入可能導致合約狀態變數(如餘額)被錯誤修改,造成不可靠或不安全的行為。
  3. 未授權操作:攻擊者可能執行未經授權的交易或操作,影響用戶及整個系統的運作。

修復方法

為避免缺乏輸入驗證的問題,開發者應採取以下措施:

  1. 確保輸入符合預期類型:檢查輸入資料是否為正確的資料類型(例如,地址、整數等)。
  2. 驗證輸入範圍:確保輸入值在可接受的範圍內(例如,金額必須為正數)。
  3. 限制函數訪問權限:確保只有授權的實體(如合約擁有者)可以調用特定功能。
  4. 檢查輸入結構:驗證輸入的格式,例如地址是否有效,或字串長度是否符合要求。
  5. 錯誤處理:當輸入無效時,立即停止執行並返回清晰的錯誤訊息。

修復後的範例合約

以下是修復了輸入驗證問題的合約範例:

// 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");

總結

缺乏輸入驗證是智能合約中常見的安全漏洞,可能導致資金損失、狀態損壞或未授權操作。透過對輸入資料進行嚴格的類型、範圍、格式和權限驗證,並在無效輸入時提供明確的錯誤訊息,開發者可以顯著提高合約的安全性和可靠性。修復後的合約展示了如何通過權限控制和輸入檢查來解決這些問題。