Skip to content

Commit

Permalink
feat(evm): ante handler to prohibit authz grant evm messages
Browse files Browse the repository at this point in the history
  • Loading branch information
onikonychev committed Sep 12, 2024
1 parent 6ba79bb commit 660f7e8
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- [#2022](https://github.com/NibiruChain/nibiru/pull/2022) - feat(evm): debug_traceCall method implemented
- [#2023](https://github.com/NibiruChain/nibiru/pull/2023) - fix(evm)!: adjusted generation and parsing of the block bloom events
- [#2031](https://github.com/NibiruChain/nibiru/pull/2031) - fix(evm): debug calls with custom tracer and tracer options
- [#2032](https://github.com/NibiruChain/nibiru/pull/2032) - feat(evm): ante handler to prohibit authz grant evm messages

#### Dapp modules: perp, spot, oracle, etc

Expand Down
1 change: 1 addition & 0 deletions app/ante.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ func NewAnteHandlerNonEVM(
) sdk.AnteHandler {
return sdk.ChainAnteDecorators(
ante.AnteDecoratorPreventEtheruemTxMsgs{}, // reject MsgEthereumTxs
ante.AnteDecoratorAuthzGuard{}, // disable certain messages in authz grant "generic"
authante.NewSetUpContextDecorator(),
wasmkeeper.NewLimitSimulationGasDecorator(opts.WasmConfig.SimulationGasLimit),
wasmkeeper.NewCountTXDecorator(opts.TxCounterStoreKey),
Expand Down
98 changes: 98 additions & 0 deletions app/ante/auth_grard_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package ante_test

import (
"time"

sdkclienttx "github.com/cosmos/cosmos-sdk/client/tx"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/authz"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"

"github.com/NibiruChain/nibiru/v2/app"
"github.com/NibiruChain/nibiru/v2/app/ante"
"github.com/NibiruChain/nibiru/v2/x/evm"
"github.com/NibiruChain/nibiru/v2/x/evm/evmtest"
)

func (s *AnteTestSuite) TestAnteDecoratorAuthzGuard() {
testCases := []struct {
name string
txMsg func() sdk.Msg
wantErr string
}{
{
name: "sad: authz generic grant with evm message",
txMsg: func() sdk.Msg {
someTime := time.Now()
expiryTime := someTime.Add(time.Hour)
genericGrant, err := authz.NewGrant(
someTime,
authz.NewGenericAuthorization(sdk.MsgTypeURL(&evm.MsgEthereumTx{})), &expiryTime,
)
s.Require().NoError(err)
return &authz.MsgGrant{Grant: genericGrant}
},
wantErr: "not allowed",
},
{
name: "happy: authz generic grant with non evm message",
txMsg: func() sdk.Msg {
someTime := time.Now()
expiryTime := someTime.Add(time.Hour)
genericGrant, err := authz.NewGrant(
someTime,
authz.NewGenericAuthorization(sdk.MsgTypeURL(&stakingtypes.MsgCreateValidator{})), &expiryTime,
)
s.Require().NoError(err)
return &authz.MsgGrant{Grant: genericGrant}
},
wantErr: "",
},
{
name: "happy: authz non generic grant",
txMsg: func() sdk.Msg {
someTime := time.Now()
expiryTime := someTime.Add(time.Hour)
genericGrant, err := authz.NewGrant(
someTime,
&banktypes.SendAuthorization{},
&expiryTime,
)
s.Require().NoError(err)
return &authz.MsgGrant{Grant: genericGrant}
},
wantErr: "",
},
{
name: "happy: non authz message",
txMsg: func() sdk.Msg {
return &evm.MsgEthereumTx{}
},
wantErr: "",
},
}

for _, tc := range testCases {
s.Run(tc.name, func() {
deps := evmtest.NewTestDeps()
anteDec := ante.AnteDecoratorAuthzGuard{}

encCfg := app.MakeEncodingConfig()
txBuilder, err := sdkclienttx.Factory{}.
WithChainID(s.ctx.ChainID()).
WithTxConfig(encCfg.TxConfig).
BuildUnsignedTx(tc.txMsg())
s.Require().NoError(err)

_, err = anteDec.AnteHandle(
deps.Ctx, txBuilder.GetTx(), false, evmtest.NextNoOpAnteHandler,
)
if tc.wantErr != "" {
s.Require().ErrorContains(err, tc.wantErr)
return
}
s.Require().NoError(err)
})
}
}
56 changes: 49 additions & 7 deletions app/ante/authz_guard.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,51 @@
// Copyright (c) 2023-2024 Nibi, Inc.
package ante

// TODO: https://github.com/NibiruChain/nibiru/issues/1915
// feat(ante): Add an authz guard to disable authz Ethereum txs and provide
// additional security around the default functionality exposed by the module.
//
// Implemenetation Notes
// UD-NOTE - IsAuthzMessage fn. Use authz import with module name
// UD-NOTE - Define set of disabled txMsgs
import (
"cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"
errortypes "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/x/authz"
"github.com/cosmos/gogoproto/proto"

"github.com/NibiruChain/nibiru/v2/x/evm"
)

var genericAuthTypeTurl = "/" + proto.MessageName(&authz.GenericAuthorization{})

// AnteDecoratorAuthzGuard filters autz messages
type AnteDecoratorAuthzGuard struct{}

// AnteHandle rejects "authz grant generic --msg-type '/eth.evm.v1.MsgEthereumTx'"
func (rmd AnteDecoratorAuthzGuard) AnteHandle(
ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler,
) (newCtx sdk.Context, err error) {
for _, msg := range tx.GetMsgs() {
if msgGrant, ok := msg.(*authz.MsgGrant); ok {
if msgGrant.Grant.Authorization == nil {
return ctx, errors.Wrapf(
errortypes.ErrInvalidType,
"grant authorization is missing",
)

Check warning on line 29 in app/ante/authz_guard.go

View check run for this annotation

Codecov / codecov/patch

app/ante/authz_guard.go#L26-L29

Added lines #L26 - L29 were not covered by tests
}
if msgGrant.Grant.Authorization.TypeUrl == genericAuthTypeTurl {
var genericAuth authz.GenericAuthorization
err = proto.Unmarshal(msgGrant.Grant.Authorization.Value, &genericAuth)
if err != nil {
return ctx, errors.Wrapf(
errortypes.ErrInvalidType,
"failed unmarshaling generic authorization",
)

Check warning on line 38 in app/ante/authz_guard.go

View check run for this annotation

Codecov / codecov/patch

app/ante/authz_guard.go#L35-L38

Added lines #L35 - L38 were not covered by tests
}
if genericAuth.MsgTypeURL() == sdk.MsgTypeURL(&evm.MsgEthereumTx{}) {
return ctx, errors.Wrapf(
errortypes.ErrNotSupported,
"authz grant generic for msg type %s is not allowed",
genericAuth.MsgTypeURL(),
)
}
}
}
}
return next(ctx, tx, simulate)
}

0 comments on commit 660f7e8

Please sign in to comment.