<aside> 🐧
This post was written when MsgForceTransfer and MsgSetBeforeSendHook were vulnerable in the previous x/tokenfactory module versions.
</aside>
The x/tokenfactory module allows users to create their own native tokens. These tokens come with powerful features, such as MsgForceTransfer and MsgSetBeforeSendHook.
MsgForceTransfer: this feature allows the token creator to forcefully transfer the tokens from any account’s balance.MsgSetBeforeSendHook: this feature allows the token creator to configure a CosmWasm contract that will be called every time a token transfer happens. This can be used to perform custom validations, such as preventing the tokens from being sent to a blocklisted recipient address due to compliance issues. If the contract returns an error, the transfer fails.What if the token creator is malicious and decides to use these features against the chain itself? 🤔
In the x/gov module, the RefundAndDeleteDeposits function transfers the deposit from the x/gov module address to the depositor. If an error occurs when transferring the funds, a panic will be triggered, causing a chain halt as this function is called within the EndBlocker.
If an attacker deposits the malicious tokens into a proposal and calls MsgForceTransfer to reduce the x/gov module balance (or disallow the funds from being transferred out from the x/gov module account with MsgSetBeforeSendHook), the chain will be halted.
The attack vectors would be:
MsgForceTransfer: a malicious token creator can forcefully reduce a module’s balance so that when the funds are transferred, the operation will fail due to insufficient balance. This works the same for MsgBurnFrom where attackers can also reduce a module account’s balance with it.
MsgSetBeforeSendHook: a malicious token creator can purposely set the hook address (msg.CosmwasmAddress) to a dummy address that fails when the Sudo call is dispatched. For example, the hook address can be an EOA address instead of a properly configured CosmWasm contract. This would cause an error when the module account tries to transfer the tokens as the required Sudo handler entry point is not found.
IsModuleAcc function that will not return an error if the tokens are being sent from a module account.MsgForceTransfer in the x/gov moduleMsgSubmitProposal and MsgDeposit allow users to send funds. These funds are not restricted to the minimum deposit tokens (i.e., params.ExpeditedMinDeposit or params.MinDeposit) by the x/gov module (update: the latest version of Cosmos SDK restricts them now). Users can send unrelated funds to the module, which will eventually be refunded or burnt in the EndBlocker.
An attacker can send malicious native tokens created in x/tokenfactory to the x/gov module. When the EndBlocker is executed, the funds are either refunded (via RefundAndDeleteDeposits) or burnt (via DeleteAndBurnDeposits), depending on the params.BurnProposalDepositPrevote configuration. In both cases, the attacker can cause the ABCI methods to panic due to an insufficient funds error, ultimately halting the chain.
params.BurnProposalDepositPrevote is false)MsgCreateDenom in the x/tokenfactory module.
MsgMint to mint some tokens.
MsgSubmitProposal to create a dummy proposal and send the minted tokens.
MsgForceTransfer to reduce the x/gov module’s balance by transferring the funds to other accounts.