How Securify pinpoints unsafe calls in smart contracts

Petar Tsankov
ChainSecurity
Published in
3 min readJul 16, 2018

The implementation of the recently proposed ERC827 token standard has a critical security issue: it allows any user to call any function in any contract with arbitrary data on behalf of the vulnerable contract. As one can expect, this vulnerability has severe consequences. For example, if the vulnerable contract contains any tokens, then an attacker could simply make a call on behalf of the vulnerable contract to transfer all tokens to herself. Further, any sensitive functions that can be executed only by the vulnerable contract can be bypassed by the attacker. This renders the vulnerable contract widely open to attackers.

Vulnerability: Unsafe calls

The underlying issue that makes the contract vulnerable is an unsafe call in the following function:

function approveAndCall(
address _spender,
uint256 _value,
bytes _data
)
public
payable
returns (bool)
{
// require(_spender != address(this));
approve(_spender, _value);
require(_spender.call.value(msg.value)(_data));
return true;
}

The unsafe call is emphasized using bold font. Important to note is that the attacker has full control over the variables _spender and _data, as their values are provided as arguments to the function. Therefore, an attacker can easily exploit the contract as follows:

  1. To call a target contract with address 0xDEADBEEF on behalf of the vulnerable contract, the attacker sets the argument _spender to 0xDEADBEEF.
  2. To call a particular function in the target contract, the attacker sets the argument _data to the hash of the function along with any arguments required by the function.

For more details on this vulnerability, we refer the reader here.

Automated detection using Securify

Securify is a security scanner for Ethereum smart contracts developed by the ICE center and ChainSecurity (for full details on how it works, you can read our technical report). Scanning the implementation of the vulnerable ERC827 token using Securify identifies several security issues:

Highlighted code lines identify security issues in the smart contract

Securify flags the vulnerable call to _spender. The detailed security pinpoints the following security issue:

Securify checks all calls in the contract and identifies the ones whose target address and provided data can be manipulated by attackers. Indeed, this is precisely what leads to the vulnerability in the ERC827 token.

In addition to this, Securify discovers several other vulnerabilities in the vulnerable ERC827 contract. For instance, it flags the function approveAndCall() because the contract does not validate the arguments provided by the user, including the values of _spender and _data.

How to stay safe?

Securify is freely available at https://securify.ch. Scan your contract today to avoid critical security vulnerabilities in your contract!

--

--