In the world of headline-grabbing smart contract exploits, developers and other stakeholders often skew their security attention in one direction; namely, they tend to focus on on-chain code, yet often neglect framework security. When writing smart contracts, this oversight can have significant negative security implications. Insecure frameworks or languages can subtly introduce vulnerabilities when compiling or adding checks around code. A tiny error on the periphery, where an organization does not double check the trust relationships between its application and the underlying framework, can result in catastrophic financial losses.

Exploitation in the Real World: Wormhole

Perhaps one of the most consequential examples of failed framework security in recent memory is the $350 million Wormhole hack  in early 2022. This attack was a direct result of the use of an insecure and deprecated function in an outdated version of Solana. The Wormhole protocol allowed the bridging of different on-chain assets between the Solana chain and other popular chains such as Ethereum. As Solana is not compatible with EVM chains, the bridging solution demanded a custom implementation for both the Solana and Ethereum sides, and each had to communicate with the other seamlessly. As it turned out, the Solana implementation of the bridge ran on Solana 1.7.0 (source), which allowed use of the insecure load_instruction_at method. While this method has since been deprecated, as Figure 1 shows, we can understand how the exploit worked by referencing reporting at the time.

Figure 1: load_instruction_at was deprecated after Solana 1.7.0

In Solana, a sysvar is a hardcoded account address that can be called to access certain state data. For example, a contract could perform a call on the SysvarC1ock11111111111111111111111111111111 account in order to read the time.

Wormhole was using the load_instruction_at method to verify that a user had input the correct sysvar account. The behavior took place in the following order:

  1. Called verify_signatures with a user-controlled sysvar account
  2. Validate the sysvar account using load_instruction_at to check that an instruction matches the expected id of the sysvar account
  3. Used the validated sysvar to verify that an account has permission to mint wrapped ETH on Solana

However, as it turned out, an attacker could spoof any address as the sysvar account using the vulnerable method. Prior to the Wormhole attack, Solana had deprecated the load_instruction_at method, replacing it with load_instruction_at_checked , which would validate that the proffered address was a real sysvar account.

While the Wormhole team had made a commit patching this issue and pushed the commit to their GitHub repository a few weeks later, an attacker was able to exploit the vulnerability to spoof a user-controlled sysvar account a few hours before Wormhole had a chance to integrate that change on-chain. The attacker created a program with an instruction that would pass the necessary check and used it as if it was a valid sysvar account to bypass the required signature validation. Since the Solana bridge used a “successful” signature validation to determine if a user had permission to mint (or unlock) Wrapped ETH (WETH) on the recipient chain, the attacker was able to fully drain the contract of its WETH collateral.

How We Patch Matters

The Wormhole hack was possible as a result of the dev team pushing framework security changes to their public GitHub repository before deploying the patch to production. In fact, the attacker exploited the project just a few hours after the patch the developers pushed the patch to GitHub.

The developers labeled the commit itself as a simple version number upgrade [ Source ] with the text “Update Solana to 1.9.4” [ Source ]. However, many additions and deletions to the code base accompanied this “simple” update, as Figure 2 demonstrates. The discrepancy between the simple commit description and the extensive changes might have prompted the attacker to pay close attention and notice the security update that the dev team pushed to GitHub but not to the on-chain smart contracts.

Figure 2: The security update was buried with many other changes in a single commit.

Wormhole could have handled this situation differently to prevent this problem from occurring. The dev team should have used a local commit containing security patches to update the programs on Solana before pushing updates to a public repository. However, this solution makes one important assumption: that the vulnerable protocol is a centralized company with a defined governance structure and clear, internal private channels of communication where this action can be easily coordinated between leadership and developers. In this case, the team behind Wormhole meets these criteria, but this is not always applicable to all Web3 projects dealing with critical security updates.

Silent Patching: A Broadly Applicable Solution

More often than not, ecosystems in Web3 are decentralized, and vulnerable resources underpinning protocols are outside the direct control of developers. Hence, we need a protocol for handling security-critical updates to decentralized networks. Go Ethereum ( geth ), the leading implementation of the ethereum protocol, is an excellent example of a core technology with wide security implications. Geth underpins roughly 75% of all ethereum nodes; therefore, in-the-wild exploitation of a critical security vulnerability in the geth implementation would be catastrophic to the ethereum protocol, and by extension, to the entire crypto ecosystem.

Geth has outlined their disclosure policy in their vulnerability disclosure document. The company follows the principle of “silent patching”, introducing two 4-8 week long delays between issuing a fix for a critical vulnerability, disclosing that the fix was security-related, and finally publishing the results of the vulnerability. This approach balances both transparency and security. We strongly recommend a similar approach for core technologies that both require users or developers to patch and would have severe implications were an attacker to uncover a framework security vulnerability before users integrate the patches.

How to Avoid This by Using the Trust Ecosystem

Wormhole fixed the vulnerability by updating their Solana version and switching to load_instruction_at_checked in commit 7edbbd . To reduce the risk of similar attacks, security conscious organizations should use up-to-date development libraries and remain on the most recent software versions when possible. Be disciplined about checking for announcements that projects have deprecated unsafe methods, as developers often do not emphasize this in update details. Also, pay particular attention to deprecation warnings during compilation and when reading documentation.

Furthermore, projects such as the Solidity compiler maintain historic lists of known bugs , which you can cross-reference against the versions your organization uses. This step functions as a backstop for human error during an initial review of documentation. While it takes extra time, double checking the trust dependencies here can reduce your organization’s vulnerability to this type of attack.

At an industry level, we advocate for more widespread adoption of transparent announcements and record-keeping in the Web3 development ecosystem. Projects such as Solana and others have the opportunity to clearly warn users when they discover potentially critical vulnerabilities in the underlying framework or language. We believe these projects have an ethical obligation to disclose framework security issues directly and in a timely manner, given the widespread trust ecosystem in which they participate.

 

Welcome to Web3 Wednesdays, where we share technical insights and solutions pertaining to smart contracts. This is the second installment in a series exploring the role of trust dependencies in smart contract security. You can find the first post here. 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