Transaction order dependence attack in smart contract

blog + secure coding + Smart contract + Solidity Z. Oualid today

share close

The transaction life cycle in most Blockchain technologies is mainly controlled by miners, even the order of the transactions. Therefore, when two users execute two different transactions at the same or closer time then only their gas fees will judge who will be executed first. This concept creates a vulnerability in smart contracts. So what is a transaction order dependence attack in smart contract?

The transaction order dependence attack in smart contract also called the Front Running attack, happens when a smart contract requires that, two transactions should be submitted and executed in the same order to get the same results.

In this blog post you are going to learn why this vulnerability exists in detail and how can an attacker exploit it. In addition, you will see in detail how you can prevent this vulnerability and fix it in your source code. All the discussions in this blog post will be accompanied by source code examples to better understand the concepts. So, if you are interested to learn more about this subject then just keep reading and leave a comment below.

What is a transaction order dependence attack in smart contract?

The transaction order dependence attack in smart contract happens when a smart contract requires that two transactions should be submitted and executed in the same order to get the same results. This simply means that if two transactions are submitted to the smart contract, then the final state of the smart contract will depend on which one of them was executed first.

Let me give you a technical example to better understand this concept. Let’s say there is a smart contract that allows people to offer their precious objects for sale. In this smart contract, the owner can change the price of his object at any moment he wants to. In addition, the smart contract allows other users to buy those objects by sending the specified sell price.

You may not notice the vulnerability in this scenario, the owner of the object may send a price changer transaction, to the smart contract at the same moment the buyer does to get the object. However, the gas price for the owner transaction is more than the buyer transaction gas price.

In this situation, the owner might be able to make the user pay more than what he was expected to do because his transaction will be executed first.

If you can’t see the impact of this vulnerability with this example, please take a look at the following section where you will get 2 smart contract codes that are vulnerable to this attack.

Technical examples of the transaction order dependence vulnerability

To better understand the concept of this vulnerability, I suggest you take a look at the following smart contracts source codes:

In this example, the smart contract offers the user the ability to win 1000 ether if he was able to find a string with the hash specified as the variable “hash”.

This smart contract is vulnerable to a transaction dependence vulnerability and the attack could be like the following:

  1. The first user will submit the solution for the hash in a transaction to the smart contract.
  2. His transaction will get to the mempool waiting to be included in the next block.
  3. An attacker is monitoring the mempool waiting for such transaction to that smart contract, and will get retrieve the solution from that transaction.
  4. Then the attack submits the same value to the smart contract but with a higher gas price.
  5. At this moment the attacker transaction will be the first to be executed which will make him the winner.

What is the impact of the transaction order dependence attack?

Like most smart contract vulnerabilities, the impact of the transaction order dependence vulnerability depends on the business logic of the smart contract. In most real-life cases, the impact is low or medium, unless there is some sort of financial loss to either the smart contract or the users.

How to discover the transaction order dependence attack in smart contract?

Many tools were developed by security researchers who are capable of discovering this kind of vulnerability. Therefore, here is a list of some of the most used ones to discover this vulnerability:

  • Securify
  • Oyente
  • Mythril

For more details on what other types of vulnerabilities can each tool discover, you can check my previous blog post.

If you don’t like to use the tools and you want to try to find those vulnerabilities manually, then here are some things you should look for while auditing your smart contract:

  1. Look for functions that change the stat of the smart contract
  2. For each function ask yourself the following question: Does the transactions order result have an impact on the output of this function
  3. If the answer to that question is YES then you have a vulnerability.

How to prevent the transaction order dependence attack?

Preventing this type of vulnerability is quite difficult compared to others, as it may require big business logic changes sometimes. However, the commit/reveal schema can be used to solve the issue. To better understand this concept let’s try to fix the previous vulnerable code discussed in the second section of this blog post.

Here is the vulnerable code:

As we said in the previous section, the solve() function of this smart contract is vulnerable to the transaction order dependence attack. Therefore, here is a fixed version of this smart contract:

Let’s analyze these smart contract functions:

  1. The commitSolutionHash() function is the function responsible for locking the contract after one of the users submits the solution hash. This is the commit function in the commit-reveal schema. The fact that we use a hash instead of the actual clear text solution, protects it from being sniffed by the attacker in the Blockchain.
  2. Once the user commits his solution hash this function gives that user a time frame of 1 hour to call the solve() function with the actual value. This protects the contract, from a DOS that the attacker could perform against this smart contract to stop any user from solving the challenge. (you can add also an array to only allow for 1 try or sending some Ethers to play)
  3. After the commit, the user calls the solve() function with the right clear text solution, plus a nonce. The nonce is used to protect the commitedHash value from being bruteforced by an attacker once the commitSolution is called first by the user. The question that you may ask now is what stops the attacker from monitoring the mempool at this level and reading the clear text from them. The short answer is that it is already too late to perform the attack. This is because to call the solve function he needs to first call the commitSolution() to change the solutionHash because that value is connected to the user address who send it.

Using a hash instead of the actual solution protects the user from leaking his solution in the Blockchain ledger.

Does the transaction order dependence attack exist in other Blockchains?

All the Blockchains that give the nodes the ability to reorder the transactions could have this vulnerability in their smart contract codes. However, Blockchain like Solana which uses the proof of history to create the order, may not be vulnerable to such attacks.

Written by: Z. Oualid

Rate it

About the author

Z. Oualid

I am a Cyber Security Expert, I have worked with many companies around the globe to secure their applications and their networks. I am certified OSCP and OSCE which are the most recognized and hard technical certifications in the industry of cybersecurity. I am also a Certifed Ethical hacker (CEH). I hope you enjoy my articles :).

Previous post

Post comments (0)

Leave a reply

Your email address will not be published. Required fields are marked *