A cross-contract re-entrancy attack detection method and system
By constructing a cross-contract function call graph and performing static taint analysis, combined with rules such as pre-payment verification and custom decorator protection, the problem of high false alarm rate in cross-contract reentrancy attack detection in blockchain smart contracts is solved, ensuring transaction security and efficient utilization of system resources.
Patent Information
- Application Number
- CN202210618214.X
- Authority / Receiving Office
- CN · China
- Patent Type
- Patents(China)
- Current Assignee / Owner
- Filing Date
- 2022-06-01
- Publication Date
- 2025-11-25
- Estimated Expiration
- 2042-06-01
AI Technical Summary
Existing technologies cannot effectively detect cross-contract reentrancy attacks in blockchain smart contracts, resulting in a high false positive rate and failing to guarantee the security of users' assets.
A static taint analysis approach is adopted. By constructing a cross-contract function call graph and combining it with the source code of smart contracts written in Solidity, static taint analysis is performed to identify suspicious paths. Reentrancy attack paths are confirmed by using rules such as pre-payment verification, custom decorator protection, and execution lock protection.
It enables accurate and rapid detection of cross-contract reentrancy vulnerabilities, reduces false positive rates, ensures transaction security, reduces system resource consumption, and enriches blockchain application scenarios.
Smart Images

Figure HDA0003673499260000011
Abstract
Description
Technical Field
[0001] This invention belongs to the field of blockchain security and provides a method and system for detecting cross-contract reentrancy attacks. Background Technology
[0002] Blockchain, as one of the hottest technologies today, is being adopted in areas such as financial services. Its transparency, traceability, immutability, and verifiability are also valuable in multi-party business collaborations, such as supply chain management. Smart contracts are special protocols designed to provide, verify, and execute contracts, allowing for traceable, irreversible, and secure transactions without the need for third parties. Smart contracts contain all the information about a transaction and only execute the resulting operation after the requirements are met. However, due to the relative immaturity of blockchain technology and the emergence of numerous smart contracts of varying quality, when a smart contract calls or utilizes the code of other external contracts, these external calls can be hijacked by attackers, forcing the contract to execute more code. Attackers can carefully construct contracts at external addresses containing malicious code in fallback functions. Therefore, when the contract sends data to this address, the malicious code is activated. Typically, the malicious code executes functions on vulnerable contracts, performing actions that the developers did not intend. The infamous The DAO incident exploited this type of attack, ultimately leading to the Ethereum hard fork.
[0003] Several preventative measures exist against reentrancy attacks, requiring programmers to be more cautious when writing contracts. One method is to use the built-in `transfer()` function when sending Ethereum to an external contract. Since this function only sends 2300 Gas to the external call, it's insufficient for the destination address contract to invoke another contract. A second technique ensures that all logic modifying state variables occurs before Ether is sent out of the contract or any external call occurs. Ideally, external calls to unknown addresses should be the last operation in a local function or code. This is referred to as the Check-Effect-Interaction pattern in Ethereum documentation. Another approach is to introduce a mutex lock, which involves adding a state variable to lock the contract during code execution, preventing reentrancy calls.
[0004] Function call graphs are typically directed acyclic graphs (DAGs). Analysis of call graphs can be divided into static and dynamic analysis. Static analysis involves analyzing the target program without running it, usually analyzing the source code or binary file. Dynamic analysis records function calls during actual program execution. The quality of the call graph obtained from source code analysis is generally related to the analysis tool's understanding of the programming language. Analysis of the target binary file typically involves disassembling the file and then analyzing the resulting text file. Dynamic analysis records function calls during program execution and then organizes them to generate a call graph. Compared to static analysis, it can obtain more information, such as the order and frequency of function calls; however, it also has some drawbacks, such as the possibility that some branches of the program's statements may not be executed, and the functions called in these branches may not be recorded.
[0005] Stain analysis can be abstracted into a triple.<sources,sinks,sanitizers> Taint analysis takes the form of a source, which represents the direct introduction of untrusted or confidential data into the system; a sink, which represents the direct occurrence of security-sensitive operations (violation of data integrity) or the leakage of private data to the outside world (violation of data confidentiality); and a sanitizer, which represents the process of encrypting data or removing harmful operations to prevent data propagation from harming the information security of the software system. Taint analysis analyzes whether data introduced by a taint source in a program can propagate directly to a taint sink without sanitizing. If not, the system's information flow is secure; otherwise, the system has security issues such as privacy data leakage or dangerous data operations.
[0006] Taint analysis techniques are also divided into static and dynamic analysis techniques. Static taint propagation analysis (STA) refers to analyzing the data dependencies between program variables to detect whether data can propagate from a taint source to a taint convergence point without running or modifying the code. The object of static taint analysis is generally the program's source code or intermediate representation, transforming the static analysis of explicit taint propagation into the analysis of static data dependencies within the program. First, a call graph is constructed based on the function call relationships in the program; then, specific data flow propagation analysis is performed within or between functions based on different program characteristics. Common explicit taint propagation methods include direct assignment propagation, propagation through function (procedure) calls, and propagation through aliases (pointers). Dynamic taint propagation analysis (VTSA) refers to the process of detecting whether tainted data can propagate from a taint source to a taint convergence point by real-time monitoring of the propagation of tainted data in the system program during program execution. VTSA first requires extending the tainted data with a taint tag and storing it in a storage unit (memory, register, cache, etc.). Then, it designs corresponding propagation logic to propagate the taint tag according to the instruction type and instruction operands. VTSA is classified into three types according to its implementation level: hardware-based, software-based, and hybrid taint propagation analysis. Summary of the Invention
[0007] This invention discloses a detection method for cross-contract call reentrancy attacks in blockchain based on static taint analysis. Smart contract reentrancy vulnerabilities are among the most serious vulnerabilities in current blockchain platforms, often leading to massive financial losses. However, general reentrancy attack detection tools experience a sharp increase in false positive rates when multiple contracts are involved. Therefore, there is a need to research cross-contract reentrancy vulnerability detection schemes. The detection method of this invention addresses the detection gap in current blockchain platform smart contracts, accurately and quickly detecting potential risks between multiple contract calls to ensure the security of users' assets.
[0008] To solve the above problems, the present invention adopts the following technical solution:
[0009] A cross-contract reentrancy attack detection system includes the following modules:
[0010] Contract processing module: Input the contract to be tested, analyze the source code of the smart contract, and generate a cross-contract function call graph of the smart contract;
[0011] Static Analysis Module: Processes the cross-contract function call graph, performs static taint analysis on the generated cross-contract function call graph, and obtains suspicious taint paths;
[0012] Path confirmation module: Based on pre-payment verification, payment address hardcoding, execution lock protection, custom modifier protection, and pre-transaction internal update rules, it comprehensively reviews suspicious paths and finally outputs the reentrancy attack path detection results.
[0013] In the above technical solution, the input to the contract processing module is a smart contract written in Solidity, which collects all calls starting from the external function, specifically including the following steps:
[0014] Step 2.1: Construct a cross-contract call graph using a Solidity program. Generate a directed cross-contract call graph where nodes are Solidity functions and directed edges represent call relationships.
[0015] Step 2.2: Add the edges represented by the fallback function and custom decorator to obtain a more accurate cross-contract call graph;
[0016] Step 2.3: For each function within the cross-contract call graph, an internal function call graph is generated after passing through the abstract parser.
[0017] Step 2.4: Combine the cross-contract call graph obtained in Step 2.2 with the internal function call graph obtained in Step 2.3 to obtain the final required cross-contract function call graph, and obtain the call chain based on the cross-contract function call graph.
[0018] In the above technical solution, the static analysis module performs static taint analysis on the cross-contract function call graph. The analysis targets all call relationships in the cross-contract call graph that start from a suspicious contract address and end with an external function call. In the cross-contract function call graph, if a path meets any of the following conditions, then the path is considered a vulnerable path subject to reentrancy attacks:
[0019] (1) The contract object called any of its public methods;
[0020] (2) The address variable called an arbitrary low-level function.
[0021] Step 3 specifically includes the following steps:
[0022] Step 3.1: A vulnerable path refers to a path that can read external input parameters and ultimately points to an unsafe function that depends on those external input parameters. The goal of this module is to identify all critical vulnerable paths in the cross-contract function call graph that could lead to reentrancy attacks. This requires considering some unique features of Solidity.
[0023] Step 3.2: Sources of taint include parameters of public functions and Solidity-specific tx.origin and msg.sender. tx.origin refers to the original external address that initiated the entire transaction, and msg.sender refers to the external address that called the current contract. Data assignment operations and function returns can lead to the propagation of tainted data. Address binding operations within Solidity programs can also lead to the propagation of tainted data.
[0024] Step 3.3 In the cross-contract function call graph, if a path satisfies any of the following conditions, then the path is considered a vulnerable path that may be subject to reentrancy attacks: (1) The contract object calls any of its public methods, because the method is very likely to contain the fallback() function; (2) The address variable calls any low-level function.
[0025] In the above technical solution, the path confirmation module uses pre-payment access control technology, payment address hard encoding, custom modifier protection, execution lock protection, and pre-payment internal upgrade technology to jointly judge suspicious paths.
[0026] This invention also provides a method for detecting cross-contract reentrancy attacks, comprising the following steps:
[0027] Contract processing steps: Input the contract to be tested, analyze the source code of the smart contract, and generate a cross-contract function call graph of the smart contract;
[0028] Static analysis steps: Process the cross-contract function call graph, perform static taint analysis on the generated cross-contract function call graph, and obtain suspicious taint paths;
[0029] Path confirmation steps: Based on pre-payment verification, payment address hardcoding, execution lock protection, custom modifier protection, and pre-transaction internal update rules, suspicious paths are comprehensively reviewed, and the reentrancy attack path detection results are finally output.
[0030] In the above technical solution, the input to the contract processing steps is a smart contract written in Solidity, which collects all calls starting from the external function, specifically including the following steps:
[0031] Step 2.1: Construct a cross-contract call graph using a Solidity program. Generate a directed cross-contract call graph where nodes are Solidity functions and directed edges represent call relationships.
[0032] Step 2.2: Add the edges represented by the fallback function and custom decorator to obtain a more accurate cross-contract call graph;
[0033] Step 2.3: For each function within the cross-contract call graph, an internal function call graph is generated after passing through the abstract parser.
[0034] Step 2.4: Combine the cross-contract call graph obtained in Step 2.2 with the internal function call graph obtained in Step 2.3 to obtain the final required cross-contract function call graph, and obtain the call chain based on the cross-contract function call graph.
[0035] In the above technical solution, the static analysis module performs static taint analysis on the cross-contract function call graph. The analysis targets all call relationships in the cross-contract call graph that start from a suspicious contract address and end with an external function call. In the cross-contract function call graph, if a path meets any of the following conditions, then the path is considered a vulnerable path subject to reentrancy attacks:
[0036] (1) The contract object called any of its public methods;
[0037] (2) The address variable called an arbitrary low-level function.
[0038] Because the present invention adopts the above-described technical solution, it has the following beneficial effects:
[0039] 1. Compared with many mainstream detection methods, this solution can solve the problem of excessively high false positive rate in cross-contract reentrancy vulnerability detection.
[0040] 2. This solution uses a lightweight symbolic execution analysis tool and performs static analysis, which avoids excessive system resource overhead.
[0041] 3. When a participant calls an external contract or sends data to an address, requiring the contract to submit an external call, this method ensures that a reentrancy attack is detected before the transaction is completed, thus preventing financial loss to the participant. This method, by introducing traditional software analysis techniques, reduces false positives while ensuring pre-transaction security, enriching the application scenarios of blockchain. Attached Figure Description
[0042] Figure 1 Contract analysis and processing. Detailed Implementation
[0043] To make the objectives, technical solutions, and advantages of this invention clearer, the invention will be further described in detail below with reference to embodiments. It should be understood that the specific embodiments described herein are only for explaining the invention and are not intended to limit the invention; that is, the described embodiments are merely some embodiments of the invention, and not all embodiments.
[0044] The detailed description of the embodiments of the present invention is not intended to limit the scope of the claimed invention, but merely to illustrate selected embodiments of the invention. All other embodiments obtained by those skilled in the art based on the embodiments of the present invention without inventive effort are within the scope of protection of the present invention.
[0045] It should be noted that relational terms such as "first" and "second" are used merely to distinguish one entity or operation from another, and do not necessarily require or imply any such actual relationship or order between these entities or operations. Furthermore, the terms "comprising," "including," or any other variations thereof are intended to cover non-exclusive inclusion, such that a process, method, article, or apparatus that comprises a list of elements includes not only those elements but also other elements not expressly listed, or elements inherent to such a process, method, article, or apparatus. Without further limitations, an element defined by the phrase "comprising one..." does not exclude the presence of other identical elements in the process, method, article, or apparatus that includes said element.
[0046] The implementation of a cross-contract reentrancy attack detection system includes:
[0047] Contract processing module: Input the contract to be tested, analyze the source code of the smart contract, generate the cross-contract function call graph of the smart contract, and thus obtain the call chain.
[0048] Static Analysis Module: Processes the call graph and performs static taint analysis on the generated cross-contract call graph to identify suspicious taint paths.
[0049] Path confirmation module: Based on rules such as pre-payment verification, payment address hardcoding, and execution lock protection, it conducts a comprehensive review of suspicious paths and finally outputs the reentrancy attack path detection results, reducing the false alarm rate of the system.
[0050] The main processes for the three modules mentioned above in this solution include:
[0051] A. The construction process of the function call graph is similar to that of the procedure call graph in a typical object-oriented language, requiring only additional consideration of the fallback function and custom decorators. After constructing the inter-contract call graph and the intra-contract function call graph, combining the two yields the cross-contract function call graph and the call chain. Taint analysis can then be performed on the call graph and the call chain.
[0052] B. Static taint analysis employs many methods similar to those in Java and C++, but it must take into account the characteristics of the Solidity language. First, data dependencies are constructed based on variables in the contract, and then suspicious paths are identified through static taint analysis.
[0053] C. For suspicious paths obtained in stage B, a comprehensive judgment is made using techniques from the path confirmation module. To make the judgment more accurate, this solution also uses lightweight symbolic analysis to assist in the judgment. The specific execution process is as follows: the user provides a threshold h, and the process iterates h times to perform cyclic analysis, that is, the return value of each function call is used as the new variable value for the next call. This step ensures that the obtained path is reachable, which greatly reduces the path judgment time and avoids potential false alarms.
[0054] I. Obtaining Suspicious Paths
[0055] A call graph is constructed using traditional methods, and then suspicious paths are obtained using the following methods: Specific steps:
[0056] a. Identify vulnerable call paths across the function call graph through static taint analysis.
[0057] b. Filter the vulnerable call paths obtained in a based on pre-payment access control technology, payment address hard encoding, custom decorator protection, execution lock protection, and pre-payment internal upgrade technology.
[0058] c. Output the remaining paths after filtering.
[0059] II. Path Filtering
[0060] Iterate through all call chains in the VC collection. If any of the following conditions exist: pre-payment access control technology, payment address hardcoding, custom decorators, execution locks, or pre-payment internal upgrades, then remove that call chain from the fragile call chain. The following is an analysis of some real-world examples that might trigger false positives:
[0061] 1) Pre-payment access control
[0062] contract CozyTimeAuction {
[0063] function buyCozy( uint256 _pepeId , uint256 _cozyCand , address _pepeRec) public payable {
[0064] require (address (pepeContract) == msg.sender);
[0065] PepeAuction storage auction = auctions[_pepeId];
[0066] totalFee = ...
[0067] auction.seller.transfer(price - totalFee);
[0068] if (!pepeContract.cozyTime(auction. pepeId , _cozyCand , _pepeRec)){...}
[0069] delete auctions[_pepeId];}...}
[0070] The code first reads the state of `auctions[_pepeID]`, then calls an external function via `pepeContract.cozyTime()`, and finally writes the result to a public variable. Some detection tools consider writing to a public variable after an external call as a potential reentrancy attack. However, because the code already performs the necessary check `require(address(pepeContract) == msg.sender)`, it does not actually trigger a reentrancy attack. Pre-payment access control checks whether `msg.sender` meets specific conditions (whether it has good credit or transaction history), and it also needs to ensure that the check statement and the statement that might trigger a reentrancy attack exist in the same function called externally to avoid false positives.
[0071] 2) Hard-coded payment address
[0072] interface HgInterface {
[0073] function buy( address _add) payable external returns( uint256 ) ;}
[0074] contract Richer3D { ...
[0075] mapping (uint256 =>DataModal.RoundInfo) rID;
[0076] HgInterface constant p3d = HgInterface(0 xB3775fB83F7D12A36E0475aBdD1FCA35c091efBe);
[0077] function calculateTarget() public {
[0078] if(increaseBalance>= targetBalance) {
[0079] if (increaseBalance > 0)
[0080] { p3d.buy. value (ethForP3D)(p3dAddress);}}...
[0081] rID[rNumber].lastTime = _timestamp ;...}}
[0082] The code above performs a balance check and conducts the transaction via a low-level call. Also, like the example in 1), it writes the public variable `rID[rNumber]` after the external call. Therefore, some detection tools might report it as having a reentrancy vulnerability. However, in reality, because the code uses a 20-byte hard-coded payment address, it cannot be modified to any other address, and thus will not trigger a reentrancy attack.
[0083] 3) Custom decorator protection
[0084] contract RTB2 {
[0085] modifier onlyHuman(){
[0086] address_addr = msg.sender;
[0087] unit256 _codeLength ;
[0088] assembly {_codeLenth := extcodesize(_addr)}
[0089] require(_codeLenth == 0, “sorry humans only”);
[0090] }
[0091] function buy(unit256 _amt) external onlyHuman payable{
[0092] require(balances[msg.sender]>= _amt);
[0093] require(msg.sender.call.value(_amt)());
[0094] balances[msg.sender] -= _amt;
[0095] }}
[0096] Some detection tools detect that the `buy()` function might be recursively called by external callers, leading to reentrancy attacks, and therefore falsely flag the above code as risky. However, the code actually takes security into account. The `OnlyHuman()` decorator is added before the `buy()` function, which is susceptible to reentrancy attacks. This decorator ensures that the transaction address can only be accessed via the keyword `extcodesize`. If this decorator is called by the contract creator, its return value is 0, thus guaranteeing that the `buy()` function will not be called by external attackers.
[0097] 4) Implement lock protection
[0098] contract ZethrBankroll is ERC223Receiving{
[0099] ZTHInterface public ZTHTKN;
[0100] bool internal reEntered;
[0101] function reveiveDividends() public payable{
[0102] if (!reEntered){
[0103] …
[0104] if (ActualBalance>0.01 ether){
[0105] reEntered = true;
[0106] ZTHTKN.buyAndSetDivpercentage.value(ActualBalance
[0107] (address(0x0), 33, “”);
[0108] reEntered = false;
[0109] }}}}
[0110] contract ZTHInterface {
[0111] function buyAndSetDivpercentage(address _referredBy,
[0112] unit8_divChoice, String provideUnhashedPass)
[0113] public payable returns (unit);
[0114] }
[0115] In the code above, some detection tools might consider `ZTHTKN.buyAndSetDivPercentage.value()` to be maliciously invoked by an external attacker, thus leading to an attack. However, the local variable `reEntered` is checked before the transaction is executed, and other function calls are not allowed before the transaction is completed. The relevant variable is only released after the transaction is completed, thus preventing malicious invocation by external attackers. Execution locks are similar to semaphores in operating systems, strictly controlling access to functions to prevent reentrancy attacks from the outset.
[0116] 5) Internal updates before the transaction
[0117] contract PvPCrash {
[0118] function withdraw() gasMin public returns (bool) {
[0119] address _user = msg.sender;
[0120] uint256 _userBalance;
[0121] if (! roundEnded&&withdrawBlock[block.number]<= maxNumBlock) {
[0122] _userBalance = getBalance(_user);
[0123] if (_balance>_userBalance) {
[0124] if (_userBalance>0) {
[0125] _user.transfer(_userBalance); / / externalCall
[0126] emit Withdraw(_user , _userBalance);}
[0127] return true;}}
[0128] return true;}}
[0129] According to CONSENSYS, a code writing pattern that prevents reentrancy attacks should include three steps:
[0130] a) Perform necessary checks before the transaction function;
[0131] b) The middle part of the code updates the state of Boolean and numeric variables;
[0132] c) The last part of the code is a call to the payment function of the external contract or address.
[0133] Some detection tools have rules that classify a transaction as potentially vulnerable to reentrancy attacks if it simultaneously meets the following conditions: reading the public variable `var`, consuming more than 2300 gas, and having a transaction amount greater than the balance; and reading the public variable `var` before an external call. While the code above meets these conditions, it adheres to safe coding patterns and therefore will not lead to a reentrancy attack.
[0134] This solution builds upon general detection tools by examining code that may be vulnerable to reentrancy attacks. It checks whether necessary pre-payment checks are performed, whether the payment address is hardcoded, whether custom decorators are added, whether execution locks are considered, and whether secure code writing patterns are followed. By comprehensively evaluating suspicious paths, it ultimately outputs accurate results indicating potential reentrancy attacks.
Claims
1. A cross-contract reentrancy attack detection system, characterized in that: Contract processing module: Input the contract to be tested, analyze the source code of the smart contract, and generate a cross-contract function call graph of the smart contract; Static Analysis Module: Processes the cross-contract function call graph, performs static taint analysis on the generated cross-contract function call graph, and obtains suspicious taint paths; Path confirmation module: Based on pre-payment verification, payment address hardcoding, execution lock protection, custom modifier protection, and pre-transaction internal update rules, it comprehensively reviews suspicious paths and finally outputs the reentrancy attack path detection results; The contract processing module takes input from a smart contract written in Solidity and collects all calls starting from the external function, specifically including the following steps: Step 2.1: Construct a cross-contract call graph using a Solidity program. Generate a directed cross-contract call graph where nodes are Solidity functions and directed edges represent call relationships. Step 2.2: Add the edges represented by the fallback function and custom decorator to obtain a more accurate cross-contract call graph; Step 2.3: For each function within the cross-contract call graph, an internal function call graph is generated after passing through the abstract parser. Step 2.4: Combine the cross-contract call graph obtained in Step 2.2 with the internal function call graph obtained in Step 2.3 to obtain the final required cross-contract function call graph, and obtain the call chain based on the cross-contract function call graph; The static analysis module performs static taint analysis on the cross-contract function call graph. The analysis targets all call relationships in the cross-contract call graph that begin with a suspicious contract address and end with an external function call. In the cross-contract function call graph, a path is considered vulnerable to reentrancy attacks if it meets any of the following conditions: (1) The contract object called any of its public methods; (2) The address variable called an arbitrary low-level function.
2. The cross-contract reentrancy attack detection system according to claim 1, characterized in that: The path confirmation module uses pre-payment access control technology, payment address hard encoding, custom modifier protection, execution lock protection, and pre-payment internal upgrade technology to jointly identify suspicious paths.
3. A method for detecting cross-contract reentrancy attacks, characterized in that: Includes the following steps: Contract processing steps: Input the contract to be tested, analyze the source code of the smart contract, and generate a cross-contract function call graph of the smart contract; Static analysis steps: Process the cross-contract function call graph, perform static taint analysis on the generated cross-contract function call graph, and obtain suspicious taint paths; Path confirmation steps: Based on pre-payment verification, payment address hardcoding, execution lock protection, custom modifier protection, and pre-transaction internal update rules, suspicious paths are comprehensively reviewed, and the reentrancy attack path detection results are finally output. The input to the contract processing steps is a smart contract written in Solidity, which collects all calls starting from the external function, specifically including the following steps: Step 2.1: Construct a cross-contract call graph using a Solidity program. Generate a directed cross-contract call graph where nodes are Solidity functions and directed edges represent call relationships. Step 2.2: Add the edges represented by the fallback function and custom decorator to obtain a more accurate cross-contract call graph; Step 2.3: For each function within the cross-contract call graph, an internal function call graph is generated after passing through the abstract parser. Step 2.4: Combine the cross-contract call graph obtained in Step 2.2 with the internal function call graph obtained in Step 2.3 to obtain the final required cross-contract function call graph, and obtain the call chain based on the cross-contract function call graph; The static analysis module performs static taint analysis on the cross-contract function call graph. The analysis targets all call relationships in the cross-contract call graph that begin with a suspicious contract address and end with an external function call. In the cross-contract function call graph, a path is considered vulnerable to reentrancy attacks if it meets any of the following conditions: (1) The contract object called any of its public methods; (2) The address variable called an arbitrary low-level function.
Citation Information
Patent Citations
Blockchain attack tracing system and method
CN111787017A
Distributed detection method for intelligent contract conflict in industrial block chain
CN113609489A