From 22c654b2000ee1b4552e74a5ad6f39a75d6b9dab Mon Sep 17 00:00:00 2001 From: Anna Shaleva Date: Thu, 23 Nov 2023 12:12:34 +0300 Subject: [PATCH] neorpc: restrict maximum subitems number in SignerWithWitness Restrict the number of Rules, Contracts and Groups. A part of #3131. Signed-off-by: Anna Shaleva --- pkg/neorpc/types.go | 9 +++++++ pkg/neorpc/types_test.go | 52 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/pkg/neorpc/types.go b/pkg/neorpc/types.go index 93e60e6a1..790d27341 100644 --- a/pkg/neorpc/types.go +++ b/pkg/neorpc/types.go @@ -115,6 +115,15 @@ func (s *SignerWithWitness) UnmarshalJSON(data []byte) error { if err != nil { return fmt.Errorf("not a signer: %w", err) } + if len(aux.AllowedContracts) > transaction.MaxAttributes { + return fmt.Errorf("invalid number of AllowedContracts: got %d, allowed %d at max", len(aux.AllowedContracts), transaction.MaxAttributes) + } + if len(aux.AllowedGroups) > transaction.MaxAttributes { + return fmt.Errorf("invalid number of AllowedGroups: got %d, allowed %d at max", len(aux.AllowedGroups), transaction.MaxAttributes) + } + if len(aux.Rules) > transaction.MaxAttributes { + return fmt.Errorf("invalid number of Rules: got %d, allowed %d at max", len(aux.Rules), transaction.MaxAttributes) + } acc, err := util.Uint160DecodeStringLE(strings.TrimPrefix(aux.Account, "0x")) if err != nil { acc, err = address.StringToUint160(aux.Account) diff --git a/pkg/neorpc/types_test.go b/pkg/neorpc/types_test.go index f0c99ea23..c817bc1e8 100644 --- a/pkg/neorpc/types_test.go +++ b/pkg/neorpc/types_test.go @@ -2,10 +2,12 @@ package neorpc import ( "encoding/json" + "fmt" "testing" "github.com/nspcc-dev/neo-go/internal/testserdes" "github.com/nspcc-dev/neo-go/pkg/core/transaction" + "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/util" "github.com/stretchr/testify/require" ) @@ -37,4 +39,54 @@ func TestSignerWithWitnessMarshalUnmarshalJSON(t *testing.T) { actual, err := json.Marshal(s) require.NoError(t, err) require.Equal(t, expected, string(actual)) + + t.Run("subitems overflow", func(t *testing.T) { + checkSubitems := func(t *testing.T, bad any) { + data, err := json.Marshal(bad) + require.NoError(t, err) + err = json.Unmarshal(data, &SignerWithWitness{}) + + require.Error(t, err) + require.Contains(t, err.Error(), fmt.Sprintf("got %d, allowed %d at max", transaction.MaxAttributes+1, transaction.MaxAttributes)) + } + + t.Run("groups", func(t *testing.T) { + pk, err := keys.NewPrivateKey() + require.NoError(t, err) + bad := &SignerWithWitness{ + Signer: transaction.Signer{ + AllowedGroups: make([]*keys.PublicKey, transaction.MaxAttributes+1), + }, + } + for i := range bad.AllowedGroups { + bad.AllowedGroups[i] = pk.PublicKey() + } + + checkSubitems(t, bad) + }) + t.Run("contracts", func(t *testing.T) { + bad := &SignerWithWitness{ + Signer: transaction.Signer{ + AllowedContracts: make([]util.Uint160, transaction.MaxAttributes+1), + }, + } + + checkSubitems(t, bad) + }) + t.Run("rules", func(t *testing.T) { + bad := &SignerWithWitness{ + Signer: transaction.Signer{ + Rules: make([]transaction.WitnessRule, transaction.MaxAttributes+1), + }, + } + for i := range bad.Rules { + bad.Rules[i] = transaction.WitnessRule{ + Action: transaction.WitnessAllow, + Condition: &transaction.ConditionScriptHash{}, + } + } + + checkSubitems(t, bad) + }) + }) }