General programming vulnerabilities in smart contracts
Introduction to Smart Contract Security
Smart contracts are programs that run on top of the blockchain’s distributed ledger. Instead of using the blockchain to perform financial transactions and synchronize accounts ledgers on each node, smart contract platforms use the blockchain’s synchronization to ensure that all nodes execute the same code in the same order. With a shared initial state and all updates made using code contained within transactions added to the ledger, the nodes in the blockchain can maintain a synchronized, distributed computer.
Smart contract platforms dramatically expand the capabilities of blockchain systems, making it possible to implement any functionality that could be written on a traditional computer. However, with this expanded functionality comes the need to ensure that these smart contracts (and the value that they store, process, and transfer) are secure.
General Smart Contract Programming Vulnerabilities
Smart contracts are computer programs that run in a completely different environment: on top of a blockchain’s distributed ledger. This means that they work in a very different way from traditional computer programs.
However, that being said, they are still computer programs. This means that smart contracts can contain many of the same vulnerabilities that exist in traditional computer programs.
Smart contract code is often designed to handle transfers of value. Blockchains were originally designed as decentralized financial systems, and many smart contract platforms are built on top of this model with integrated cryptocurrencies.
Smart contracts with the ability to transfer value need to ensure that transaction requests are legitimate. A common way of accomplishing this is to test if the value transferred is less than or equal to the amount of value stored within a given account.
This dependence on integer comparisons creates the potential for integer overflow and underflow vulnerabilities:
- Integer Overflow: Attempting to store a value greater than the maximum value that a variable can hold results in truncation of leading bits and storage of a much smaller value.
- Integer Underflow: Storing a value less than the minimum value that a variable can hold results in it “rolling over” to the largest possible value that can be stored.
The image above shows sample smart contract code that contains an integer underflow vulnerability in line 2. The subtraction operation is performed using unsigned integers, which can only hold values that are greater than or equal to zero. This means that any value of _amount that results in a non-zero value after the subtraction will pass the test and allow the transfer to occur.
An attacker can exploit this by requesting a withdrawal of an amount greater than their account balance. If the smart contract contains sufficient value to support the withdrawal (i.e. other user accounts make up the deficit), then the withdrawal will be successful. While the user’s account balance will be negative after the fact, this has no impact to the attacker since they already have the money and blockchain immutability makes it impossible to reverse the malicious transaction.
Right-to-Left Control Character Obfuscation
Arithmetic vulnerabilities are a smart contract issue that can hurt the developer. The use of right-to-left control characters can enable a malicious smart contract developer to trick smart contract users.
One of the defining features of blockchain technology is its transparency. Every transaction stored on the digital ledger is accessible to every node in the network. Since smart contracts are created and called via transactions, this makes them publicly visible as well.
This makes it possible for users of a smart contract to perform code reviews. They can either reverse engineer the code contained within the contract or take advantage of the fact that some developers will post their source code for public review.
Ethereum’s support for right-to-left control characters – intended for use in Arabic and similar languages – makes it possible for an attacker to design a smart contract that is misleading when reviewed. By inserting these characters in comments – which are ignored by the Ethereum Virtual Machine but not by sites printing source code – a malicious developer can make a function’s arguments or other contents look different than it is. This makes it possible to create unwinnable contests or other malicious smart contracts.
Securing Smart Contracts
Arithmetic vulnerabilities and right-to-left overrides are only two of the types of vulnerabilities that smart contracts share with “traditional” programs. When developing smart contracts, it is essential to consider the types of normal vulnerabilities that also exist in smart contracts. For example, many of the OWASP Top Ten List of vulnerabilities for web applications also apply to the blockchain.