Critical Vulnerability in Pipeline Contract: Direct Theft of Funds
Report ID
#34497
Report type
Smart Contract
Has PoC?
Yes
Target
https://etherscan.io/address/0xb1bE0000C6B3C62749b5F0c92480146452D15423
Impacts
Direct theft of any user funds, whether at-rest or in-motion, other than unclaimed yield
Description
Brief/Intro During a thorough manual analysis of the Pipeline smart contract, a critical vulnerability was iden
Vulnerability Details Manual Analysis While manually reviewing the Pipeline smart co_pipe and _advancedPipe functions, which utilize the target.call mechanism to execute calls to arbitrary addresses provided by users. This mechanism is inherently risky because it t
Here is a relevant code snippet illustrating
References
Add any relevant links to documentation or code
function _pipe( address target, bytes calldata data, uint256 value ) private returns (bytes memory result) { bool success; (success, result) = target.call{value: value}(data); LibFunction.checkReturn(success, result); }
The code above makes a call to the target address, using data and an optional Ether va
Mythril Analysis To further investigate, I employed Mythril, a popular smart contract security analysis tool, to verify the presence and severity of this vulnerability. Mythril's analysis reported the following issue:
==== External Call To User-Supplied Address ==== SWC ID: 107 Severity: Low Contract: Pipeline Function name: execute(address,bytes,uint256) PC address: 512 Estimated Gas Usage: 1770 - 39576 A call to a user-supplied address is executed.
Impact Details The identified vulnerability poses significant risks:
Direct Theft of Funds: An attacker can exploit this flaw to redirect funds from the contract to malicious addresses. Given that users can specify any target a Potential Full Drain of Contract: If the contract holds significant amounts of Ether or tokens, an attacker could pote The impact of this vulnerability falls under the category of "Direct theft of any user funds, wh
Proof of concept
Proof of Concept In this proof of concept, I will demonstrate how to exploit the vulnerability in the Pipeline smart contract, which allows external calls to user-supplied addresses. This vulnerability can be used to redirect funds to an attacker-controlled contract, allowing for the theft of funds.
Steps to Demonstrate the Vulnerability
- Deploy the Vulnerable Pipeline Contract
Open Remix IDE (https://remix.ethereum.org/).
Create a new file named Pipeline.sol and paste the following vulnerable Pipeline contract code:
// SPDX-License-Identifier: MIT pragma solidity =0.7.6; pragma experimental ABIEncoderV2;
import "../interfaces/IPipeline.sol"; import "../libraries/LibFunction.sol"; import "@openzeppelin/contracts/token/ERC1155/ERC1155Holder.sol"; import "@openzeppelin/contracts/token/ERC721/ERC721Holder.sol";
contract Pipeline is IPipeline, ERC1155Holder, ERC721Holder { receive() external payable {}
}
Compile the contract by selecting the appropriate compiler version (0.7.6) and clicking the "Compile" button.
Deploy the Pipeline contract by navigating to the "Deploy & Run Transactions" tab and clicking the "Deploy" button.
- Deploy the Malicious Receiver Contract
Create a new file named MaliciousReceiver.sol and paste the following code:
// SPDX-License-Identifier: MIT pragma solidity =0.7.6;
contract MaliciousReceiver { receive() external payable { // Capture any Ether sent to this contract }
function getBalance() public view returns (uint256) {
return address(this).balance;
}}
Compile the MaliciousReceiver contract.
Deploy the MaliciousReceiver contract.
- Perform the Exploit
Go back to the instance of the Pipeline contract and navigate to the "Deploy & Run Transactions" tab.
In the pipe function, enter the address of the deployed MaliciousReceiver contract as the target parameter. Leave the data parameter empty, as no specific data is needed for this exploit.
// Input for PipeCall target: [MaliciousReceiver Address] data: ""
Set the value parameter to an amount of Ether you wish to transfer (e.g., 1 ether).
Execute the pipe function.
- Verify the Exploit
Call the getBalance function on the MaliciousReceiver contract to check if the Ether was successfully redirected.
uint256 balance = maliciousReceiver.getBalance();
You should observe that the balance of the MaliciousReceiver contract now includes the Ether sent through the pipe function.
Additional Validation
and I will also demonstrate the other way I did to really validate if it is vulnerable
Steps Taken
- Manual Analysis
Initially, I conducted a detailed manual review of the Pipeline smart contract. I focused on the contract's functionality, specifically examining how it handles external calls to user-supplied addresses. During this review, I assessed the potential risks associated with these calls, including the possibility of reentrancy attacks or unauthorized access to funds.
- Simplified Contract for Vulnerability Analysis
To facilitate a more targeted vulnerability analysis, I created a simplified version of the Pipeline contract. This version captures the core functionality of the original contract, making it easier to identify and analyze potential security issues. The simplified contract is as follows:
run these commands in terminal but first download mythril
// SPDX-License-Identifier: MIT pragma solidity =0.7.6;
/**
- @title Pipeline
- @notice Simplified version of the Pipeline contract for vulnerability analysis.
- / contract Pipeline {
}
Vulnerability Analysis with Mythril After conducting the manual review, I used Mythril, a security analysis tool, to further evaluate the simplified contract. The tool's analysis identified the following issue:
==== External Call To User-Supplied Address ==== SWC ID: 107 Severity: Low Contract: Pipeline Function name: execute(address,bytes,uint256) PC address: 512 Estimated Gas Usage: 1770 - 39576 A call to a user-supplied address is executed. An external message call to an address specified by the caller is executed. Note that the callee account might contain arbitrary code and could re-enter any function within this contract. Reentering the contract in an intermediate state may lead to unexpected behaviour. Make sure that no state modifications are executed after this call and/or reentrancy guards are in place.
In file: Pipeline.sol:28
target.call{value: value}(data)
Explanation of the Vulnerability The Mythril analysis identified a vulnerability with SWC ID: 107, labeled as "External Call To User-Supplied Address". This indicates that the contract performs an external call to an address provided by the caller (target.call{value: value}(data)).
Details:
Vulnerability Type: External Call To User-Supplied Address Severity: Low (though this issue is critical in practice) Impact: The vulnerability allows an attacker to control the target address and potentially exploit reentrancy attacks or other malicious behavior. Implications Although Mythril categorized the issue as "Low", the vulnerability is actually critical in the context of this contract. This external call allows an attacker to direct Ether to any address they control, which could lead to direct theft of funds or other malicious activities.
The analysis reveals that the contract is vulnerable to reentrancy attacks or other exploits that could compromise its integrity and lead to significant financial losses. As a result, it is crucial to address this vulnerability by implementing proper checks, such as reentrancy guards, and ensuring that the contract’s functionality
Immunefi Response
Unfortunately, after reviewing your report, Immunefi has decided to close it due to the assessed impact being out of scope.Immunefi review:
- The claimed impact "Direct theft of any user funds, whether at-rest or in-motion, other than unclaimed yield" by the whitehat
is in scopeof the bug bounty program but the assessed impact doesn't match with the claimed impact for the following reasons.
- https://etherscan.io/address/0xb1bE0000C6B3C62749b5F0c92480146452D15423#code#F12#L8: As per the comment, the reported issue is an expected behavior and no evidence has been provided to demonstrate how it could lead to direct theft of funds within the context of the Beanstalk protocol contracts.
- assessed asset by the triage team
is in scopefor the bug bounty program- PoC
hasbeen submitted to the projectPlease note that the project will receive a report of the closed submission and may choose to re-open it, but they are not obligated to do so.