Auditing Cross-Chain Messaging Risk with Glider

Auditing Cross-Chain Messaging Risk with Glider
Share

Intro

The Web3 ecosystem is home to a wide range of attack vectors, spanning everything from smart contract vulnerabilities to Web2 infrastructure weaknesses. In some of the most damaging exploits, failures don't stem from a single flaw but from several issues compounding into one catastrophic failure. A particularly underexplored vector is cross-chain messaging configuration, where a single misconfiguration can allow hackers to pass forged messages and drain hundreds of millions in assets, impacting not just the targeted protocol but interconnected platforms like Aave, Compound, and more.

How can protocol devs, risk analysts, and retail investors stay ahead of these risks? Audits can surface misconfigurations, but only reflect the state of a protocol at a single point in time. Behavioral analysis from data providers offers another layer of visibility, but falls short when it comes to identifying admin configurations or detecting changes to those configurations in real time.

With static code analysis powered by Glider, teams can identify intricate LayerZero configurations, collecting critical data on DVN addresses, admins, settings, and more. This tooling gives risk managers, analysts, and investors the visibility needed to better assess the risk of a protocol and its associated contracts. As Web3 protocols grow increasingly interconnected, the need for automated tooling to identify complex configurations and periphery attack vectors has never been greater.

LayerZero Misconfigurations

Some protocols use LayerZero to receive tokens from other chains via their own deployed OApp contracts. When a protocol misconfigures its DVN setup, requiring only a single DVN to verify to cross-chain messages, it creates a critical single point of failure. A DVN acts as a verifier, responsible for confirming the legitimacy of messages received from another chain before the protocol processes them. With only one DVN in place, an attacker who compromises that single verifier can forge a cross-chain message and have it accepted.

For any given LayerZero configuration, major red flags include:

- Only 1 required DVN to verify
- No optional DVNs configured
- Optional DVN threshold too low relative to the total DVN count

More advanced checks include:

- Are any DVN contracts vulnerable to security exploits
- Are any DVN contract admins vulnerable to security exploits
- Are any LayerZero delegates vulnerable to security exploits

With all this in mind, let's look at how Glider can help identify these misconfigurations.

Glider Examples

Glider is a static code analysis engine that allows you to write queries in Python to scan contracts across an entire chain. Queries can run continuously and across multiple chains. Glider can also read a contract's current state and other critical contract data. Together, these features enable sophisticated analyses on everything from smart contract risks to state analysis.

Below are two examples of how Glider can identify LayerZero misconfigurations and more:

Example #1 - Identifying Poor DVN Settings

Glider can identify various LayerZero misconfigurations by reading the UlnConfig values set for both the send and receive libraries of a given OApp. To do this, Glider follows three steps:

1. Find all EIDs for the given OApp
2. Enumerate through each EID
3. Read the configuration for the given OApp + EID + Lib and determine the DVN settings

This can be done by running the following Glider query:

```python
from glider import *

def query():
endpointContracts = (
Contracts()
.with_function_signature("getConfig(uint32,address,uint32)")
.mains()
.exec(1)
)

endpointContract \= endpointContracts\[0\]  
oAppContractAddress \= "0x85d456B2DfF1fd8245387C0BfB64Dfb700e98Ef3"  
  
dvnSettings \= retrieveUlnConfigSettings(endpointContract.address(), oAppContractAddress)  
  
vulnerableOAppContracts \= \[\]  
  
for dvnSetting in dvnSettings:  
    safeThreshold \= isSafeThreshold(dvnSetting)  
    safeConfirmation \= isSafeConfirmation(dvnSetting)  
    safeRequired \= isSafeRequired(dvnSetting)  
  
    if not safeThreshold or not safeConfirmation or not safeRequired:  
        return Contracts().with\_address(oAppContractAddress).exec(1)  

\# No results found  
return \[\]  

# Code related to state-reading omitted for brevity
```

With this Python query, we can retrieve the relevant DVN settings, validate them, and return the offending OApp contract in the Glider results.

Example #2 - Scanning DVN Contracts For Risks

In this example, we take the query one step further, analyzing the DVN addresses themselves to determine whether each address is a contract, if so, what type of multisig it is, and whether it contains any security risks.

Using similar logic from the first query, we retrieve the DVN addresses, query each one, and identify traits and risks for each address:

```python
from glider import *

def query():
endpointContracts = (
Contracts()
.with_function_signature("getConfig(uint32,address,uint32)")
.mains()
.exec(1)
)

endpointContract \= endpointContracts\[0\]  
oAppContractAddress \= "0x85d456B2DfF1fd8245387C0BfB64Dfb700e98Ef3"  
  
dvnSettings \= retrieveUlnConfigSettings(endpointContract.address(), oAppContractAddress)  
  
vulnerableAdmins \= \[\]  
  
for dvnSetting in dvnSettings:  
    dvnRequiredAddresses \= getRequiredAddresses(dvnSetting)  
    dvnOptionalAddresses \= getOptionalAddresses(dvnSetting)  
    for dvnAddress in dvnRequiredAddresses \+ dvnOptionalAddresses:      
        dvnContract \= Contract().with\_address(dvnAddress).exec()  
        if dvnContract:  
            hasRisk \= validateRisk(dvnContract)  
            if hasRisk:  
                vulnerableAdmins.append(dvnContract)  

\# No results found  
return vulnerableAdmins  

# Code related to state-reading omitted for brevity
```

When analyzing multisig contracts, Glider can run the following risk checks:

- What is the signature threshold?
- Can signature authentication be bypassed?
- If it is a Gnosis Safe contract, are the correct Safe-specific guards in place?

Unlike transactional analysis, static code analysis allows Glider to analyze smart contract code directly, identify risky code patterns, and surface critical insights into complex risk configurations.

Conclusion

LayerZero misconfiguration exploits serves as a stark reminder that Web3 protocols are only as secure as their weakest configuration. As protocols grow increasingly interconnected, a single misconfiguration in a third-party integration like LayerZero's DVN settings can cascade into hundreds of millions in losses across the broader ecosystem. Risk managers and retail investors alike can no longer rely solely on point-in-time audits or transaction analysis to stay ahead of these attack vectors.

Static code analysis powered by Glider changes this dynamic. By continuously scanning configurations, DVN settings, admin addresses, and multisig risks across an entire chain, Glider equips the Web3 community with the automated tooling necessary to proactively identify and respond to these complex periphery risks. The protocols and investors who leverage this tooling will be far better positioned to understand not just what a protocol does, but how safely it is configured to do it.

Community members

[ Our community ]

[ Community hires ]