Skip to content
Last updated: March 11, 2025

SCWE-011: Insecure ABI Encoding and Decoding

Stable Version v0.0.1

This content is in the version-(v0.0.1) and still under active development, so it is subject to change any time (e.g. structure, IDs, content, URLs, etc.).

Send Feedback

Relationships

Description

Insecure ABI encoding and decoding occur when a smart contract improperly handles data serialization and deserialization, leading to vulnerabilities such as data corruption, type confusion, or reentrancy attacks. Solidity provides ABI encoding functions like abi.encode(), abi.encodePacked(), and abi.decode(), but improper usage can cause unexpected behavior.

Common issues with insecure ABI handling: - Collision Risks in abi.encodePacked(): Multiple concatenated parameters can lead to ambiguous encoding, making it vulnerable to hash collisions. - Unchecked Decoding: Improper use of abi.decode() can result in unintended memory corruption or type confusion. - Lack of Input Validation: Encoding user inputs without verification can introduce security flaws. - Mismatched Data Types: Decoding an incorrectly encoded data structure can lead to invalid memory access.

Remediation

  • Use abi.encode() Instead of abi.encodePacked() for Hashing: Prevent collision risks by ensuring unique encoding.
  • Validate Data Before Decoding: Ensure the encoded data conforms to the expected structure before decoding.
  • Match Encoding and Decoding Types: Always use the correct type structure when decoding to avoid unintended behavior.
  • Avoid Direct ABI Decoding of External Calls: Use strict validation mechanisms when handling data from external contracts.

Examples

Example of Insecure ABI Encoding:

pragma solidity ^0.8.0;

contract InsecureABI {
    function hashValues(string memory str, uint256 num) public pure returns (bytes32) {
        return keccak256(abi.encodePacked(str, num)); // ❌ Collision risk
    }
}
  • In this example, abi.encodePacked() creates a collision risk because different input combinations can produce the same hash.

Refactored to Secure ABI Encoding:

pragma solidity ^0.8.0;

contract SecureABI {
    function hashValues(string memory str, uint256 num) public pure returns (bytes32) {
        return keccak256(abi.encode(str, num)); // ✅ Unique encoding, no collision
    }
}
  • In this improved version, abi.encode() ensures a unique encoding structure, preventing hash collision attacks.