EOS Smart Contracts Security Audit — A Comprehensive Guide
By Shivank Chopra Blockchain Developer at QuillHash
EOS platform has created much hype in the blockchain community by offering a high transaction rate and providing an operating system like architecture for managing distributed resources. Companies and developers are quickly adopting and moving on to build their next dApps on EOS. Since the smart contracts supported by EOS are converted to web assembly, C++ was the language of choice for developing them.
The ecosystem around EOS is still in its early stages, and the tools, technologies and practices around developing EOS smart contracts have yet to mature. Smart contracts generally involve transfer of funds, thus it becomes very important to audit them extensively before they become live. Unique design of EOS and it’s choice of language (C++) makes the audit process of the smart contracts fundamentally different from other popular platforms like Ethereum. Through this article, we intend to list various language and platform based parameters that must be checked during the smart contract audit process for EOS.
1. Dangling pointers and references, proper memory management
These parameters about EOS contracts are the consequence of using C++ to write smart contracts. While programming with C++, we need to manage allocation and deallocation of memory for the instances that are created dynamically during runtime. Dangling pointers (and references) refer to the memory locations that was previously held by some objects which are now deallocated. This part of the memory may be reallocated to some other object, which can cause the original pointer (or reference) to now point at this reallocated data.
This can cause unpredictability in our application. Usage of dangling pointers inside code can at very least cause undesirable behaviour, in some cases corruption of data, and can even be exploited maliciously. Dangling pointers can be targeted by adding malicious code to the memory locations pointed to by them, so that during their further use in application logic, malicious data is introduced in the system and may cause undesirable behavior.
2. Checking for Buffer Overflow
Buffer overflow is a flaw where while writing data to a buffer, the program exceeds the limit of the buffer and overwrites the memory locations adjacent to the buffer boundaries. This can happen when we have an assumption on the size of inputs to the buffer for a certain operation. If the input happens to be larger than our assumed value, it may start to overwrite on the memory locations adjacent to the the memory locations of the buffer.
Exploiting buffer overflow is a known security vulnerability. Basic idea is to provide inputs with malicious data that are large enough to cause buffer overflow, and overwrite other variables of the application logic. This way, by influencing data in the input, attacker can try to influence the program into producing desirable outputs. Further if poorly designed smart contract code is made publicly available, it will give attackers an ample opportunity to analyse the structure and perform buffer overflows on the vulnerable parts of the contract.
3. Custom Dispatcher and mapping of actions to roles and permissions
In EOS, the publicly available executable functions of the smart contract are called actions. Each action can be called upon by the accounts interacting with the smart contract. These actions may have some permission level associated with them, which can be easily handled while using the default permissions (owner or active). Mapping of actions to the permissions is handled by the dispatcher, which is the first entry point inside the contract. It is specified using EOSIO_DISPATCH macro.
However, many times we may need to add custom permissions in our application. In that case we need to write a custom dispatcher, that maps the actions to the custom permissions. A poorly mapped action to a permission level may leave the smart contract code open to malicious actors, that can have unauthorised access to the actions. Proper permissions and authorisation management inside an operation is a general practice that must be followed in developing smart contracts on any platform.
4. Dependence of transferring funds on predictable outcomes, handling random numbers
This is especially true for betting games type contracts that depend on some condition like value of some random number to decide the winner and transfer funds to the winner account. In a well known incident, attackers made an identical contract and were able to generate the winning numbers beforehand. This led them to place correct bets each time and transferred funds to themselves.
It should be noted that it is not possible to obtain non deterministic values in a deterministic environment. Blockchain frameworks like EOS have to be deterministic in nature as a transaction on one EOS node must be identical on every other node in order to ensure consensus. However there are ways to generate random numbers as explained here.
5. Handling persistent data on RAM, usage of multi index table
EOS provides the RAM as the resource for fast access and persisting application data. The access to the RAM is provided by the EOS library in form of multi index tables. These tables are capable of storing any kind of data specified through a struct object passed while instantiating them. These tables are generally used to store important contract specific data like balances or whitelisted accounts.
So in the absence of proper checking during arithmetic operations over this data can cause the values to overflow, an hence result in data loss. This can especially be dangerous if the records being corrupted points to the balances of accounts. As a good practice, always use the asset structure provided by the eosio library. It overloads all the basic arithmetic operators and its usage is preferred over extracting balances and then performing operations.
6. Transfer error prompts
The EOS smart contracts provide the functionality to respond to notifications from other contracts. Thus when there is no proper checking on the context of notifications, a fake notification can be designed to trigger the action on the victim contract. In a famous betting game hack, fake notifications were used to trigger transfer funds action of the contract, and the attackers were able to transfer funds to themselves by providing fake notifications to the victim contract. To avoid this, we should check all the parameters from the notifications and respond only to those notifications that are of interest to the current contract.
In this article, we covered some general hotspot areas inside the EOS smart contracts that must be inspected while auditing them. This list is by no means exhaustive, and we will continue to discover and index more vulnerable areas about EOS smart contracts as it matures. Further speaking, it is highly advisable to get your contracts audited by trusted 3rd party companies offering auditing services. At QuillAudits, we have a proven track record of developing and auditing smart contracts on major blockchain platforms.
Thanks for reading. Hopefully this guide has been useful to you and will help you to understand the common hotspots and pitfalls in EOS smart contracts Audit and Also do check out our earlier blog posts.
Stay tuned for the next parts…
Part 3 — Understanding fundamental concepts for writing dApps on EOS.
Part 4- Analysing EOS standard token contract .
Part 5- Develop a basic crowd sale application with EOS .
Part 6- EOS for high performance dApps — Games on EOS!