Merge pull request #776 from CosmWasm/limit-stargate-querier

Verify Stargate Queries handles properly
This commit is contained in:
Ethan Frey
2022-03-09 12:26:39 +01:00
committed by GitHub
2 changed files with 68 additions and 0 deletions

View File

@@ -4,6 +4,7 @@ import (
"encoding/json"
"errors"
"fmt"
"strings"
"github.com/cosmos/cosmos-sdk/baseapp"
@@ -269,8 +270,19 @@ func IBCQuerier(wasm contractMetaDataSource, channelKeeper types.ChannelKeeper)
}
}
var queryDenyList = []string{
"/cosmos.tx.",
"/cosmos.base.tendermint.",
}
func StargateQuerier(queryRouter GRPCQueryRouter) func(ctx sdk.Context, request *wasmvmtypes.StargateQuery) ([]byte, error) {
return func(ctx sdk.Context, msg *wasmvmtypes.StargateQuery) ([]byte, error) {
for _, b := range queryDenyList {
if strings.HasPrefix(msg.Path, b) {
return nil, wasmvmtypes.UnsupportedRequest{Kind: "path is not allowed from the contract"}
}
}
route := queryRouter.Route(msg.Path)
if route == nil {
return nil, wasmvmtypes.UnsupportedRequest{Kind: fmt.Sprintf("No route to query '%s'", msg.Path)}

View File

@@ -382,6 +382,62 @@ func TestReflectStargateQuery(t *testing.T) {
assert.Equal(t, expectedBalance, protoResult.Balances)
}
func TestReflectInvalidStargateQuery(t *testing.T) {
cdc := MakeEncodingConfig(t).Marshaler
ctx, keepers := CreateTestInput(t, false, ReflectFeatures, WithMessageEncoders(reflectEncoders(cdc)), WithQueryPlugins(reflectPlugins()))
keeper := keepers.WasmKeeper
funds := sdk.NewCoins(sdk.NewInt64Coin("denom", 320000))
contractStart := sdk.NewCoins(sdk.NewInt64Coin("denom", 40000))
creator := keepers.Faucet.NewFundedAccount(ctx, funds...)
// upload code
reflectCode, err := ioutil.ReadFile("./testdata/reflect.wasm")
require.NoError(t, err)
codeID, err := keepers.ContractKeeper.Create(ctx, creator, reflectCode, nil)
require.NoError(t, err)
require.Equal(t, uint64(1), codeID)
// creator instantiates a contract and gives it tokens
contractAddr, _, err := keepers.ContractKeeper.Instantiate(ctx, codeID, creator, nil, []byte("{}"), "reflect contract 1", contractStart)
require.NoError(t, err)
require.NotEmpty(t, contractAddr)
// now, try to build a protobuf query
protoRequest := wasmvmtypes.QueryRequest{
Stargate: &wasmvmtypes.StargateQuery{
Path: "/cosmos.tx.v1beta1.Service/GetTx",
Data: []byte{},
},
}
protoQueryBz, err := json.Marshal(ReflectQueryMsg{
Chain: &ChainQuery{Request: &protoRequest},
})
require.NoError(t, err)
// make a query on the chain, should be blacklisted
_, err = keeper.QuerySmart(ctx, contractAddr, protoQueryBz)
require.Error(t, err)
require.Contains(t, err.Error(), "path is not allowed from the contract")
// and another one
protoRequest = wasmvmtypes.QueryRequest{
Stargate: &wasmvmtypes.StargateQuery{
Path: "/cosmos.base.tendermint.v1beta1.Service/GetNodeInfo",
Data: []byte{},
},
}
protoQueryBz, err = json.Marshal(ReflectQueryMsg{
Chain: &ChainQuery{Request: &protoRequest},
})
require.NoError(t, err)
// make a query on the chain, should be blacklisted
_, err = keeper.QuerySmart(ctx, contractAddr, protoQueryBz)
require.Error(t, err)
require.Contains(t, err.Error(), "path is not allowed from the contract")
}
type reflectState struct {
Owner string `json:"owner"`
}