Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Insecure Address Parsing in BytesHelperLib.sol #217

Open
3 tasks
0xM3R opened this issue Feb 10, 2025 · 0 comments
Open
3 tasks

Insecure Address Parsing in BytesHelperLib.sol #217

0xM3R opened this issue Feb 10, 2025 · 0 comments
Assignees

Comments

@0xM3R
Copy link

0xM3R commented Feb 10, 2025

Severity: Low (Previously assessed as High)
Affected Component: @zetachain/toolkit/contracts/BytesHelperLib.sol
Impact: Programmatic Error (Minimal Security Risk)

Summary

The function bytesMemoryToAddress in BytesHelperLib.sol does not validate that the input byte array is at least 20 bytes long. This results in an unexpected programmatic error where the function reads uninitialized memory, returning a random address composed partially of zeroed-out memory. While initially classified as a security vulnerability, further analysis confirmed that the attacker cannot control or manipulate the resulting address, significantly reducing the risk.

Technical Details

The function bytesMemoryToAddress is implemented as follows:

function bytesMemoryToAddress(bytes memory data, uint256 offset) internal pure returns (address output) {
    // No validation for data.length >= offset + 20
    assembly {
        output := mload(add(add(data, offset), 32))
    }
}

Issue:

  • The function lacks a validation check to ensure that data.length >= offset + 20.
  • An attacker can provide an improperly sized input (e.g., a 19-byte payload), causing the function to read beyond the provided data and into uninitialized memory. This returns an invalid, randomized address.

Example Payload:

bytes memory payload = hex"0123456789abcdef0123456789abcdef012345"; // 19 bytes

Resulting Address: 0x89aBcDEF01234500000000000000000000000000 (random due to uninitialized memory).

Analysis:

  • The resulting address cannot be controlled by the attacker, and there is no exploitable vector for transferring funds or unauthorized actions.
  • The issue is a programmatic error rather than a security vulnerability.

Proposed Fix

Add a length check to ensure the input data is at least 20 bytes long before reading memory.

function bytesMemoryToAddress(bytes memory data, uint256 offset) internal pure returns (address output) {
    require(data.length >= offset + 20, "BytesHelper: invalid address length");
    assembly {
        output := mload(add(add(data, offset), 32))
    }
}

Next Steps

  • Apply the proposed length validation to prevent unexpected behavior. @fadeev
  • Write unit tests to ensure the updated function behaves as expected. Validate that it rejects any payload shorter than 20 bytes and correctly parses valid addresses. @fadeev
  • Clarify the toolkit development status in the ZetaChain Bug Bounty Program to set clear expectations for external security researchers. @CharlieMc0 @0xM3R

Additional Notes

  • This issue has been confirmed as low impact with minimal security risk.
  • The toolkit is under development and has not yet been audited.
  • Internal alignment is required to determine how best to address this in the context of the bug bounty program.
@fadeev fadeev self-assigned this Feb 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants