Assessment reports>ZetaChain>High findings>No panic handler in Zetaclient may halt cross-chain communication
Category: Coding Mistakes

No panic handler in Zetaclient may halt cross-chain communication

High Severity
High Impact
Medium Likelihood

Description

The code under zetaclient/ implements two separate clients — an EVM client for all EVM-compatible chains and a Bitcoin client for the Bitcoin chain. The clients are intended to relay transactions between chains as well as watch for cross-chain interactions (via emitted events).

Impact

In the event that a panic occurs in the zetaclient code, the client will simply crash. If a malicious actor is able to find a reliable way to cause panics, they can effectively halt all cross-chain communications by crashing all of the clients for that specific chain.

We discovered a bug in the Bitcoin client that can allow a malicious actor to achieve this; however, there may be numerous other ways to do this. The bug exists in the Bitcoin client's TryProcessOutTx() function.

func (signer *BTCSigner) TryProcessOutTx(send *types.CrossChainTx, outTxMan *OutTxProcessorManager, outTxID string, chainclient ChainClient, zetaBridge *ZetaCoreBridge) {
	// [ ... ]

	// FIXME: config chain params
	addr, err := btcutil.DecodeAddress(string(toAddr), config.BitconNetParams)

	if err != nil {
		logger.Error().Err(err).Msgf("cannot decode address %s ", send.GetCurrentOutTxParam().Receiver)
		return
	}

    // [ ... ]
}

Specifically, the call to btcutil.DecodeAddress() can panic if the toAddr provided to it is not a valid Bitcoin address. This is easily achieved by passing in an EVM-compatible address instead. The following stack trace is observed when the crash occurs:

zetaclient0   | panic: runtime error: index out of range [65533] with length 256
zetaclient0   |
zetaclient0   | goroutine 12508 [running]:
zetaclient0   | github.com/btcsuite/btcutil/base58.Decode({0xc005e9f968, 0x14})
zetaclient0   | 	/go/pkg/mod/github.com/btcsuite/btcutil@v1.0.3-0.20201208143702-a53e38424cce/base58/base58.go:58 +0x305
zetaclient0   | github.com/btcsuite/btcutil/base58.CheckDecode({0xc005e9f968?, 0xc001300000?})
zetaclient0   | 	/go/pkg/mod/github.com/btcsuite/btcutil@v1.0.3-0.20201208143702-a53e38424cce/base58/base58check.go:39 +0x25
zetaclient0   | github.com/btcsuite/btcutil.DecodeAddress({0xc005e9f968?, 0xc0061a6de0?}, 0x458b080)
zetaclient0   | 	/go/pkg/mod/github.com/btcsuite/btcutil@v1.0.3-0.20201208143702-a53e38424cce/address.go:182 +0x2aa
zetaclient0   | github.com/zeta-chain/zetacore/zetaclient.(*BTCSigner).TryProcessOutTx(0xc004aed680, 0xc006691680, 0xc00053aab0, {0xc00484edc0, 0x4a}, {0x32c9040?, 0xc0050ba200}, 0xc000e9af00)
zetaclient0   | 	/go/delivery/zeta-node/zetaclient/btc_signer.go:213 +0x893
zetaclient0   | created by github.com/zeta-chain/zetacore/zetaclient.(*CoreObserver).startSendScheduler
zetaclient0   | 	/go/delivery/zeta-node/zetaclient/zetacore_observer.go:224 +0x1045

Recommendations

The bug demonstrated above is in an external package that is not maintained by the ZetaChain team. Since it is not sustainable to go through and fix any such bugs that arise from the use of external packages, we recommend adding a panic handler to the Zetaclient code so that panics are handled gracefully and preferably logged, so they can be taken care of later.

Remediation

This issue has been acknowledged by ZetaChain, and a fix was implemented in commit f2adb252.

Zellic © 2024Back to top ↑