A security issue with Ethereum’s Solidity language, not just the DAO

Another issue in Solidity, a JavaScript-like language that Ethereum uses for smart contracts, has been highlighted that can impact any Ethereum contract, not just the DAO.

This issue is specifically a problem with the design of the Solidity language. There is a rich body of research on formal languages for contracts (see this survey or this post by Nick Szabo). Ethereum, however, decided to use a JavaScript-like language instead.

The issue impacts some, and not all, contracts on Ethereum. And developers of future contracts can avoid writing exploitable contracts by closely following guidelines and best practices.

This does NOT mean that Ethereum is permanently broken. The Solidity compiler can warn programmers of this particular issue.

What’s the issue?

Ethereum contracts call out to other contracts routinely. This practice is encouraged by the community with a vision of smart contracts everywhere talking to each other.

Turns out that when an Ethereum contract talks to another contract, it can lose its own program control and state. This vulnerability was discovered by Joey Krug and Martin Köppelmann, and publicized by Philip Daian, a PhD student at Cornell studying with Emin Gun Sirer.

It’s important to differentiate this issue from reentrancy, which is a known issue and was used to attack the DAO. This issue is a slightly different form of reentrancy and the subtle details are important. Let’s call this issue solarstorm (for the lack of a better name). Daian didn’t explicitly name it, but likes the solar-storm name.

Solarstorm vs. Reentrancy:

This issue might look similar to reentrancy, but it’s broader than reentrancy and developers need to think about shared state explicitly.

The reentrancy issue can happen when:

1. Contract A, function A calls contract B.
2. Contract B calls contract A, function A.

The key insight by Daian is that even a single call out by any contract is enough. The solar-storm issue can happen when:

1. Contract A calls out to any arbitrary external contract.
2. Contract A has an external function that modifies state (most do).

So an example of solar-storm exploit can be:

1. Contract A, function A calls contract B.
2. Contract A has another function C that shares state with function A.
3. Contract B calls contract A, function C.

This means that in Ethereum contracts you either (a) cannot use external calls in your contract or (b) you cannot have externally callable functions that share state with functions that make external calls.

Getting rid of (a) is hard in practice, so this means that you basically need to be very careful about (b). If you must have external calls, then you can only use them at the end of your own logic and once the external call is executed you cannot assume anything about the state of your contract.

This can be viewed as a variant of reentrancy, but it’s a broader issue than reentrancy and easier to miss.

Even if the other issue (unchecked-send and reentrancy) were not there, solarstorm alone is sufficient to steal $150M from the DAO.

What does this mean?

To summarize:

  1. This can impact any contract on Ethereum, not just the DAO. This is an issue with Ethereum’s JavaScript-like programming language (Solidity).
  2. It’s possible to have issues in already published Ethereum contracts. Developers should check if their contracts are vulnerable and take appropriate actions (move funds, publish new contracts).
  3. Developers need to be extremely careful with making external calls in future contracts. Avoid external calls until this issue is addressed.
  4. Ethereum is NOT permanently broken. Solidity compiler can warn programmers of this particular exploit.

Next steps:

A full-review of all published smart contracts is needed. We also need a static analyzer to catch the vulnerability and the Solidity compiler should detect this issue. This vulnerability is not yet widely publicized and the Solidity documentation should warn people about it.

Comments? Tweet them @muneeb. Thanks Philip Daian for helpful discussions and Elizabeth Stark for reading drafts of this post. See my earlier post on Ethereum for challenges with using a turing-complete language.

Show your support

Clapping shows how much you appreciated Muneeb Ali’s story.