The rise of the crypto industry, more adoption, the entry of new users, and complex applications have attracted hackers who are always looking to exploit the space. The attackers keep on scouting the on-chain contracts for any exposed vulnerability and take advantage of it.
These vulnerabilities lead to huge financial losses, loss of community trust, and collapse of the protocol. Considering all these facts, it is more important than ever to create a pre-deployment pipeline of the smart contracts and off-chain infrastructure, which includes robust testing and auditing of the code.
This blog explores certain Penetration Testing techniques. These techniques are essential to proactively identify and mitigate any vulnerabilities around smart contracts and the app infrastructure.
Here are 7 must-know Web3 penetration testing techniques to help secure your smart contracts:
This comes as a first step, as it doesn’t require any smart contract execution; it is just plain and simple code analysis to catch some low-hanging fruit. This process involves scanning through the source code and looking for vulnerabilities. This process also ensures you understand what you’re dealing with. This helps to map out the whole code structure and how the efficient mapping of smart contracts can be done.
This process would help find some vulnerabilities, which are as follows:
Integer Overflow/Underflow: Check for any situations where the variable can exceed the storage limit assigned to it. It could be in a case where the program is using uint8
(8-bit unsigned integer) and the value exceeds 8 bits, and similar for the underflow conditions. This vulnerability can lead to unexpected application behaviour.
Reentrancy Bugs: These bugs are common and can be easily avoided by using the Openzeppelin Reentrancy Guard
in your contracts. It lets the attacker make an external call before the contract state updates, which can lead to siphoning of the contract’s funds.
Gas Limit Issues: These issues can occur more often when certain functions or transactions exceed the gas limit and start to fail, leading to unexpected behavior.
Think of it as the start of your testing process, which would scan and remove some easily findable bugs. Remember, we are thinking how a hacker would think, this is the first thing they do to your smart contracts, scan through them.
This requires some more expertise, as this process would test the business logic and how the application performs under certain conditions. It includes writing certain scripts to interact with Smart Contracts and testing the business logic. The contracts need to be deployed locally in a local testnet (using Foundry or Hardhat) or Tenderly.
Once the deployment is done locally, scripts can be written to test different components of the application. This would find certain errors, which are as follows:
Logic Errors: These are the most important to catch, as they can lead to something that shouldn’t have occurred. This examines whether the business logic of the application matches the code written.
Access Control Issues: As an auditing firm, while auditing contracts and doing hack analysis, these are the most important issues. If access to a certain function is easily granted, which should only be callable by the admin, then it can lead to certain cascading effects.
Unexpected Interactions with Other Contracts: This helps to assess the vulnerabilities that arise when the smart contract tries to communicate with other deployed smart contracts.
This technique is one of the most important techniques, its core focus is on challenging the business logic of the application and testing any behaviour that isn’t anticipated.
Fuzzing is a very common term these days in blockchain security. It involves feeding the smart contract with a large volume of random inputs, which can lead to finding any unexpected behaviour in the smart contracts. This approach can find edge cases more easily due to its automated nature than manual code review.
This process can be classified as Automated Pentesting and can help in the following:
Edge Case Detection: Fuzz Testing can help identify how the smart contract handles inputs that are unexpected to be given by the user.
Enhancing Code Reliability: It helps in enhancing the code reliability and robustness as it has been fed with random and semi-random inputs.
DOS(Denial of Service) Attacks: These attacks are very common, where the exploiter feeds the contract with a large amount of inputs and makes it unusable.
Moreover, Fuzz Testing is a great tool for finding logical errors, integer underflow/overflow, and certain vulnerabilities in smart contracts.
Formal Verification is an important technique as it takes the verification of smart contracts and their intended behaviour to the mathematical level. It can be done using the K Framework. This process is a little resource-intensive but ensures the contract behaves correctly.
The Formal Verification allows developers to understand if the contract’s code is working as intended. It helps to verify the business logic. Consider formal verification as a way to verify a set of expected behaviors from a function or contract, these verification processes should always return true under program execution. There are two types of specifications that can be provided during Formal Verification, which are High-level and Low-level. The former is a high-level specification of the contract, considering the safety measures and intended behavior of a particular function, and the latter is a low-level specification of the contract, which tracks the contract’s traces and internal execution.
Attacks don’t simply happen on the smart contracts, but hackers can also exploit the off-chain infrastructure.
It is important to understand and analyze the system by performing active pentesting and checking the system for the following attack vectors:
Considering the above attack vectors on the off-chain infrastructure helps to understand any vulnerabilities around the cloud pipeline, databases, and DApp (Decentralized App) Interaction.
This is less seen or talked about, but every auditing firm does this process when they audit the smart contracts, and the protocols should also.
It involves mapping out the execution/flow that a transaction in a certain contract would go through. It is a map to identify what interaction a smart contract or a certain transaction would do in its lifetime.
For example, A user who borrows from a lending and borrowing protocol depends on lenders, price oracle, and liquidation mechanisms in their transaction lifetime. Hence, it becomes important to analyze this dependency and understand whether any vulnerability, like Price Manipulation Attack, Flashloan Attack, or Governance Attack, can harm the system or not.
Gas Analysis involves analyzing the contracts to determine if they can be introduced to certain attack vectors like Denial of Service (DOS), as contracts could run out of gas. Gas optimization also helps in making contracts more efficient, as saving on gas means less costs to users and deployment costs to the protocol.
The following are certain tools that can be utilized while doing smart contract and Infrastructure testing:
Smart Contract attacks are increasing in the crypto ecosystem. Most of these attacks stem from certain common attack vectors. These vectors are often ignored while writing smart contracts, but are essential to address while testing them.
Robust Testing and Auditing smart contracts and the core infrastructure is a crucial process that needs to be included in the pre-deployment pipeline, considering the immutable nature of the blockchain.
The blog summarizes different Web3 penetration techniques that can be adopted while testing your smart contracts and off-chain infrastructure.