CVE-2024-24560
Executive Summary
CVE-2024-24560 is a vulnerability in the Vyper smart contract language for the Ethereum Virtual Machine (EVM). The flaw arises from an overlapping memory buffer allocation during external contract calls: the input buffer is written starting at byte 28, while the return buffer is allocated starting at byte 0, causing them to overlap. When checking RETURNDATASIZE for dynamic types, the size is compared only to the minimum allowed size for that type, not to the actual returned data length. This allows a malicious contract to return malformed ABIv2 encoded data, causing the calling contract to misinterpret data from the dirty input buffer as legitimate return data. The CVSS score is 3.7 (Low), but the vulnerability can lead to logic errors and potential exploitation in DeFi or other smart contract applications.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
Vyper is a Pythonic smart contract language used to develop Ethereum-based applications. This vulnerability affects the Vyper compiler itself, meaning any contract compiled with a vulnerable version may be at risk. Since Vyper is distributed via PyPI and GitHub, supply chain risks include:
- Compromised compiler binaries: An attacker could inject malicious code into the Vyper compiler, leading to widespread exploitation.
- Dependency confusion: If Vyper is pulled from an untrusted source, the vulnerability could be introduced.
- Version pinning: Developers must ensure they use a patched version of Vyper to avoid this issue.
CVSS Breakdown & Threat Level
- CVSS Score: 3.7 (Low)
- Vector: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N
- Attack Vector: Network (AV:N) – the vulnerability is exploitable via network calls to smart contracts.
- Attack Complexity: High (AC:H) – requires a malicious contract to craft specific malformed return data.
- Privileges Required: None (PR:N) – no authentication needed.
- User Interaction: None (UI:N) – no user action required.
- Scope: Unchanged (S:U) – the vulnerable component remains the same.
- Confidentiality Impact: Low (C:L) – limited information disclosure from the dirty buffer.
- Integrity Impact: None (I:N) – no data modification.
- Availability Impact: None (A:N) – no denial of service.
Threat Level: Low. The vulnerability requires a malicious contract to be called and return specially crafted data, making exploitation complex. However, in DeFi contexts, it could lead to financial loss if critical logic relies on return data.
Deep Dive & Mechanics
The vulnerability lies in Vyper’s handling of external contract calls. When a Vyper contract calls an external contract, the input buffer is written starting at byte 28 (likely to leave room for the function selector at bytes 0-3). The return buffer is allocated starting at byte 0, overlapping with the input buffer. This means that if the external contract returns less data than expected, the calling contract may read leftover data from the input buffer instead of the actual return data.
The issue is compounded by the RETURNDATASIZE check: for dynamic types (e.g., arrays, strings), Vyper only checks that the returned size is at least the minimum allowed size for that type, not the exact length of the returned data. As a result, a malicious contract can return a small amount of data (e.g., just the length prefix) and the calling contract will read the rest from the dirty input buffer, potentially interpreting attacker-controlled data as legitimate return values.
Example Scenario:
- Contract A calls Contract B with a function that returns a dynamic array.
- Contract B returns only the length prefix (e.g., 32 bytes) instead of the full array.
- Vyper checks
RETURNDATASIZEagainst the minimum size for a dynamic array (32 bytes) and passes the check. - Contract A reads the array elements from the overlapping input buffer, which may contain attacker-controlled data from the original call input.
This can lead to logic errors, such as incorrect token balances, price feeds, or authorization checks.
Vulnerable vs. Patched Code
Vulnerable Code (Vyper < 0.3.10):
# In the compiler's ABI encoding/decoding logic
# Input buffer starts at byte 28, return buffer at byte 0
# RETURNDATASIZE check only compares to minimum size
if returndatasize < min_size_for_type:
revert()
# No check for exact size or buffer overlap
Patched Code (Vyper >= 0.3.10):
# Properly separate input and return buffers
# Ensure RETURNDATASIZE matches expected return data length
if returndatasize != expected_size:
revert()
# Or use separate memory regions for input and return data
The patch ensures that the return buffer does not overlap with the input buffer and that RETURNDATASIZE is checked against the exact expected size, not just the minimum.
Exploitation & Lab Setup
Red Team (Offensive)
Lab Setup:
- Install Vyper compiler version < 0.3.10.
- Set up a local Ethereum testnet (e.g., Ganache or Hardhat).
- Deploy a vulnerable Vyper contract that calls an external contract.
Exploitation Steps:
- Create a malicious contract that returns malformed ABIv2 encoded data.
- Deploy the malicious contract and call the vulnerable contract, passing attacker-controlled input.
- The vulnerable contract will read the dirty buffer, allowing the attacker to manipulate return values.
Example Malicious Contract (Solidity):
contract Malicious {
function attack() external returns (uint256[] memory) {
// Return only the length prefix (32 bytes) instead of full array
assembly {
return(0, 32) // Return 32 bytes of zeros (length = 0)
}
}
}
Vulnerable Vyper Contract:
@external
def call_external(addr: address) -> uint256:
# Calls external contract expecting a dynamic array
result: uint256[] = staticcall(addr, 0x...)
# result may contain attacker-controlled data from input buffer
return result[0]
Blue Team (Defensive)
Detection:
- Monitor for unusual external call patterns where return data size is smaller than expected.
- Use static analysis tools to detect overlapping buffer allocations in Vyper contracts.
- Implement runtime checks in contracts to validate return data length and content.
Mitigation:
- Upgrade Vyper compiler to version 0.3.10 or later.
- In contracts, add explicit checks for return data size and integrity.
- Use safe external call libraries that handle ABI decoding properly.
Indicators of Compromise (IOCs)
- On-chain: Contracts compiled with Vyper < 0.3.10 that make external calls with dynamic return types.
- Transaction patterns: Transactions where
RETURNDATASIZEis less than expected for the called function. - Logs: Revert events with
RETURNDATASIZEmismatch errors. - File hashes: Vyper compiler binaries with SHA256 hashes matching vulnerable versions (e.g., 0.3.9).
Detection Engineering
YARA Rule
rule CVE_2024_24560_Vyper_Buffer_Overlap {
meta:
description = "Detects Vyper compiler versions with overlapping buffer allocation"
author = "Valters IT"
date = "2025-04-10"
cve = "CVE-2024-24560"
strings:
$vuln_pattern = { 1c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1c } // byte 28 allocation
$min_size_check = { 3d 20 00 00 00 } // RETURNDATASIZE check for minimum size
condition:
$vuln_pattern and $min_size_check
}
Sigma Rule
title: CVE-2024-24560 Vyper Buffer Overlap Detection
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects potential exploitation of CVE-2024-24560 in Ethereum transactions
logsource:
category: blockchain
product: ethereum
detection:
selection:
event: "RETURNDATASIZE"
size: "< expected"
condition: selection
falsepositives:
- Legitimate contracts with variable-length returns
level: low
Suricata Rule
alert ip any any -> any any (msg:"CVE-2024-24560 Vyper Buffer Overlap Exploit"; content:"|1c 00 00 00|"; offset:0; depth:4; sid:1000001; rev:1;)
Remediation & Mitigation
- Upgrade Vyper Compiler: Update to version 0.3.10 or later, which fixes the buffer overlap and size check issues.
- Recompile Contracts: Recompile all Vyper contracts with the patched compiler and redeploy them.
- Runtime Validation: Add explicit checks in smart contracts to validate return data size and content after external calls.
- Use Safe Libraries: Employ well-audited libraries for external calls and ABI decoding.
- Monitor Transactions: Watch for anomalous
RETURNDATASIZEvalues in transactions involving Vyper contracts. - Conduct Audits: Perform security audits on all Vyper contracts to identify potential exploitation paths.
Valters IT
Securing the Digital Frontier