<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.