Skip to content
This repository was archived by the owner on Apr 4, 2024. It is now read-only.

Commit 145ac0c

Browse files
fix: add authz ante handler (#1741)
* imp: remove distribution perms * update changelog * fix: add authz ante handler * fix tests * fix constants * remove unnecesary setup * fix commit * fix lint * Address changes in authz.go and partially refactor unit tests * Refactor duplicate test utils and improve naming * Refactor test suite to improve code quality * Fix EIP-712 testutil comment header * Add DisabledAuthzMsgs to handler options * Add ante test * Add minor code-quality refactors --------- Co-authored-by: Austin Chandra <austinchandra@berkeley.edu>
1 parent d1935f7 commit 145ac0c

13 files changed

+1182
-7
lines changed

app/ante/ante_test.go

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -798,7 +798,7 @@ func (suite AnteTestSuite) TestAnteHandler() {
798798
signing.SignMode_SIGN_MODE_DIRECT,
799799
msg,
800800
"ethermint_9000-1",
801-
2000,
801+
2000000,
802802
"EIP-712",
803803
)
804804

@@ -831,7 +831,7 @@ func (suite AnteTestSuite) TestAnteHandler() {
831831
signing.SignMode_SIGN_MODE_DIRECT,
832832
msg,
833833
"ethermint_9000-1",
834-
2000,
834+
2000000,
835835
"EIP-712",
836836
)
837837

@@ -860,12 +860,48 @@ func (suite AnteTestSuite) TestAnteHandler() {
860860
signing.SignMode_SIGN_MODE_DIRECT,
861861
msg,
862862
"ethermint_9000-1",
863-
2000,
863+
2000000,
864864
"EIP-712",
865865
)
866866

867867
txBuilder.SetMsgs(msg, msg)
868868

869+
return txBuilder.GetTx()
870+
}, false, false, false,
871+
},
872+
{
873+
"Fails - Authz Exec with unauthorized message",
874+
func() sdk.Tx {
875+
ethTx := evmtypes.NewTx(
876+
suite.app.EvmKeeper.ChainID(),
877+
1,
878+
&to,
879+
big.NewInt(10),
880+
100000,
881+
big.NewInt(150),
882+
big.NewInt(200),
883+
nil,
884+
nil,
885+
nil,
886+
)
887+
ethTx.From = addr.Hex()
888+
889+
msg := authz.NewMsgExec(
890+
sdk.AccAddress(privKey.PubKey().Address()),
891+
[]sdk.Msg{ethTx},
892+
)
893+
894+
txBuilder := suite.CreateTestSingleSignedTx(
895+
privKey,
896+
signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON,
897+
&msg,
898+
"ethermint_9000-1",
899+
200000,
900+
"",
901+
)
902+
903+
txBuilder.SetMsgs(&msg)
904+
869905
return txBuilder.GetTx()
870906
}, false, false, false,
871907
},

app/ante/authz.go

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// Copyright 2021 Evmos Foundation
2+
// This file is part of Evmos' Ethermint library.
3+
//
4+
// The Ethermint library is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Lesser General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// The Ethermint library is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Lesser General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Lesser General Public License
15+
// along with the Ethermint library. If not, see https://github.com/evmos/ethermint/blob/main/LICENSE
16+
package ante
17+
18+
import (
19+
"fmt"
20+
21+
errorsmod "cosmossdk.io/errors"
22+
sdk "github.com/cosmos/cosmos-sdk/types"
23+
errortypes "github.com/cosmos/cosmos-sdk/types/errors"
24+
"github.com/cosmos/cosmos-sdk/x/authz"
25+
)
26+
27+
// maxNestedMsgs defines a cap for the number of nested messages on a MsgExec message
28+
const maxNestedMsgs = 6
29+
30+
// AuthzLimiterDecorator blocks certain msg types from being granted or executed
31+
// within the authorization module.
32+
type AuthzLimiterDecorator struct {
33+
// disabledMsgs is a set that contains type urls of unauthorized msgs.
34+
disabledMsgs map[string]struct{}
35+
}
36+
37+
// NewAuthzLimiterDecorator creates a decorator to block certain msg types
38+
// from being granted or executed within authz.
39+
func NewAuthzLimiterDecorator(disabledMsgTypes []string) AuthzLimiterDecorator {
40+
disabledMsgs := make(map[string]struct{})
41+
for _, url := range disabledMsgTypes {
42+
disabledMsgs[url] = struct{}{}
43+
}
44+
45+
return AuthzLimiterDecorator{
46+
disabledMsgs: disabledMsgs,
47+
}
48+
}
49+
50+
func (ald AuthzLimiterDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
51+
if err := ald.checkDisabledMsgs(tx.GetMsgs(), false, 0); err != nil {
52+
return ctx, errorsmod.Wrapf(errortypes.ErrUnauthorized, err.Error())
53+
}
54+
return next(ctx, tx, simulate)
55+
}
56+
57+
// checkDisabledMsgs iterates through the msgs and returns an error if it finds any unauthorized msgs.
58+
//
59+
// This method is recursive as MsgExec's can wrap other MsgExecs. nestedMsgs sets a reasonable limit on
60+
// the total messages, regardless of how they are nested.
61+
func (ald AuthzLimiterDecorator) checkDisabledMsgs(msgs []sdk.Msg, isAuthzInnerMsg bool, nestedMsgs int) error {
62+
if nestedMsgs >= maxNestedMsgs {
63+
return fmt.Errorf("found more nested msgs than permitted. Limit is : %d", maxNestedMsgs)
64+
}
65+
for _, msg := range msgs {
66+
switch msg := msg.(type) {
67+
case *authz.MsgExec:
68+
innerMsgs, err := msg.GetMessages()
69+
if err != nil {
70+
return err
71+
}
72+
nestedMsgs++
73+
if err := ald.checkDisabledMsgs(innerMsgs, true, nestedMsgs); err != nil {
74+
return err
75+
}
76+
case *authz.MsgGrant:
77+
authorization, err := msg.GetAuthorization()
78+
if err != nil {
79+
return err
80+
}
81+
82+
url := authorization.MsgTypeURL()
83+
if ald.isDisabledMsg(url) {
84+
return fmt.Errorf("found disabled msg type: %s", url)
85+
}
86+
default:
87+
url := sdk.MsgTypeURL(msg)
88+
if isAuthzInnerMsg && ald.isDisabledMsg(url) {
89+
return fmt.Errorf("found disabled msg type: %s", url)
90+
}
91+
}
92+
}
93+
return nil
94+
}
95+
96+
// isDisabledMsg returns true if the given message is in the set of restricted
97+
// messages from the AnteHandler.
98+
func (ald AuthzLimiterDecorator) isDisabledMsg(msgTypeURL string) bool {
99+
_, ok := ald.disabledMsgs[msgTypeURL]
100+
return ok
101+
}

0 commit comments

Comments
 (0)