As blockchain and crypto technology transitions from experimental to mainstream, the importance of top-tier security is becoming increasingly relevant. As we discussed in a recent post, organizations are grappling with the fact that risk transference–planning to insure against a cybersecurity incident, or to pay damages out of pocket–is becoming more costly than simply investing in the best security possible. The simplest web3 breaches can cost organizations millions in damages, but recent significant cases resulted in losses of hundreds of millions or even more. Insurance costs also are on the rise. Even the most expensive coverage does nothing to protect a company’s reputation in the event of a cybersecurity breach. Reputational damage compounds the already massive financial impact as the media immediately picks up and publicizes these incidents. At the heart of many breaches is a lack of understanding of web3 trust dependencies.
A Recent Example
A recent web3 exploit that demonstrates the severity of these breaches is the April 2022 Fei Protocol hack, in which the protocol suffered an exploit resulting in $80 million of stolen assets. The Fei Protocol made use of Rari Fuse lending pools, which are forked from Compound, a well-known and trusted decentralized lending platform. This dependency meant that security issues that affected Compound also affected the Fei Protocol. Public audits of Compound implementations indicate that some token standards (such as ERC-777 tokens) can be leveraged to perform reentrancy attacks. Compound limits issues with reentrancy by whitelisting implementations of safe token standards (such as ERC-20) within its ecosystem and by restricting gas forwarded to untrusted contracts (using transfer() rather than call()). The Fei Protocol team was not aware of these limitations, and chose to implement a global (cross-contract) reentrancy lock. Unfortunately, one of the functions in the borrowing flow, exitMarket(), did not include the nonReentrant modifier (see figure).
Figure: The exitMarket() function lacks a nonReentrant modifier.
Normally, an attacker would not have been able to exploit this issue. The original Compound implementation of this function included a transfer() function, which restricts the gas forwarded to the attacker. The ceiling of 2300 severely limits subsequent attacker functionality. However, a year earlier, the transfer() method called by exitMarket() had been switched out for a regular call() function that does not include such gas limitations, allowing the attacker to receive all forwarded gas and perform the reentrancy attack.
Dependency attacks like these can be very nasty. Companies lose millions of dollars because their project developers are not deeply aware of code. Furthermore, vulnerabilities in popular projects can affect many dependents. In this case, other forks of Compound, such as CREAM, BurgerSwap, and HundredFinance, were vulnerable to very similar attacks.
The Triad of Trust Dependencies
When securing smart contracts, trust is the most important factor. Specifically, the trustworthiness of the developers and auditors, and the code’s dependencies. Developers build projects for their customers, staking their reputations on the security of their work. Auditors review the code and publish audits, staking their reputations on their ability to find vulnerabilities developers missed. Finally, web3 projects almost always depend on open-source code published by other more “trusted” projects, relying on their reputations.
Established Does Not Equal Secure
This triad of dependencies means that a failure on the part of one could negatively affect the reputations of countless other individuals and projects. However, repeating all the vulnerability assessments for every open source project involved in an organization’s web3 architecture can become incredibly expensive. Therefore, at some point the industry decides a particular piece of code or project is trustworthy simply because they must prioritize their limited cybersecurity resources.
Generally, the longer a project has been around, the more users it has. Consequently, the higher the volume of users, the more secure the general crypto community perceives it to be. But that is often a false assumption. Some of the largest, most established projects at the time have been victims to largest and most devastating losses. Poly Network, Wormhole, and The DAO are only a few examples.
Traditional Web3 Security is Self-Limiting
Traditionally, security teams have focused their efforts on verifying the resilience of on-chain assets. They prioritize verifying that the individual contracts are secure. For example, in the EVM space, frameworks like the SWC Registry and tools like Mythril and Slither secure individual contracts. However, this means security teams have focused less on the security of dependencies, which have a ripple effect as we just discussed. Even those efforts take an outside-in approach, as with tools such as Dependency-Check and databases like OSV, which exist to monitor vulnerabilities within project dependencies but do not seek to resolve any issues.
Instead, Focus on the Dependencies
Our intention with our forthcoming series is to discuss the impact of dependency security within web3, where the forms that dependencies take may look different. Developers and auditors must be aware of multiple dependencies when ensuring the security of smart contracts. Key dependencies include development frameworks, third party oracles, front-end interfaces, “Grandfather Forks,” and protocol design.
Staying aware of the security impact that other codebases have on your decentralized app is key to remaining trusted. We firmly believe the web3 development community should take steps to formalize trust within the ecosystem. We are excited to dive into all the ways to solve this complex problem.
Welcome to Web3 Wednesdays, where we share technical insights and solutions pertaining to smart contracts. This is the first installment in a series exploring the role of trust dependencies in smart contract security. Future posts will highlight common flaws we have observed during the course of our work and research. If you’d like to chat with us about smart contracts or any other cybersecurity question, please reach out via our Contact Us page.