Skip to content

Commit

Permalink
Disallow array parameters in JSONRPC methods
Browse files Browse the repository at this point in the history
  • Loading branch information
2opremio committed Apr 3, 2024
1 parent 1f735e2 commit a3ba87e
Show file tree
Hide file tree
Showing 13 changed files with 95 additions and 28 deletions.
3 changes: 1 addition & 2 deletions cmd/soroban-rpc/internal/methods/get_events.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"time"

"github.com/creachadair/jrpc2"
"github.com/creachadair/jrpc2/handler"

"github.com/stellar/go/strkey"
"github.com/stellar/go/support/errors"
Expand Down Expand Up @@ -429,7 +428,7 @@ func NewGetEventsHandler(eventsStore *events.MemoryStore, maxLimit, defaultLimit
maxLimit: maxLimit,
defaultLimit: defaultLimit,
}
return handler.New(func(ctx context.Context, request GetEventsRequest) (GetEventsResponse, error) {
return NewHandler(func(ctx context.Context, request GetEventsRequest) (GetEventsResponse, error) {
return eventsHandler.getEvents(request)
})
}
3 changes: 1 addition & 2 deletions cmd/soroban-rpc/internal/methods/get_latest_ledger.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"

"github.com/creachadair/jrpc2"
"github.com/creachadair/jrpc2/handler"

"github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/db"
)
Expand All @@ -20,7 +19,7 @@ type GetLatestLedgerResponse struct {

// NewGetLatestLedgerHandler returns a JSON RPC handler to retrieve the latest ledger entry from Stellar core.
func NewGetLatestLedgerHandler(ledgerEntryReader db.LedgerEntryReader, ledgerReader db.LedgerReader) jrpc2.Handler {
return handler.New(func(ctx context.Context) (GetLatestLedgerResponse, error) {
return NewHandler(func(ctx context.Context) (GetLatestLedgerResponse, error) {
tx, err := ledgerEntryReader.NewTx(ctx)
if err != nil {
return GetLatestLedgerResponse{}, &jrpc2.Error{
Expand Down
3 changes: 1 addition & 2 deletions cmd/soroban-rpc/internal/methods/get_ledger_entries.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"fmt"

"github.com/creachadair/jrpc2"
"github.com/creachadair/jrpc2/handler"
"github.com/stellar/go/support/log"
"github.com/stellar/go/xdr"

Expand Down Expand Up @@ -40,7 +39,7 @@ const getLedgerEntriesMaxKeys = 200

// NewGetLedgerEntriesHandler returns a JSON RPC handler to retrieve the specified ledger entries from Stellar Core.
func NewGetLedgerEntriesHandler(logger *log.Entry, ledgerEntryReader db.LedgerEntryReader) jrpc2.Handler {
return handler.New(func(ctx context.Context, request GetLedgerEntriesRequest) (GetLedgerEntriesResponse, error) {
return NewHandler(func(ctx context.Context, request GetLedgerEntriesRequest) (GetLedgerEntriesResponse, error) {
if len(request.Keys) > getLedgerEntriesMaxKeys {
return GetLedgerEntriesResponse{}, &jrpc2.Error{
Code: jrpc2.InvalidParams,
Expand Down
4 changes: 1 addition & 3 deletions cmd/soroban-rpc/internal/methods/get_ledger_entry.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import (
"fmt"

"github.com/creachadair/jrpc2"
"github.com/creachadair/jrpc2/handler"

"github.com/stellar/go/support/log"
"github.com/stellar/go/xdr"

Expand All @@ -33,7 +31,7 @@ type GetLedgerEntryResponse struct {
// Deprecated. use NewGetLedgerEntriesHandler instead.
// TODO(https://github.com/stellar/soroban-tools/issues/374) remove after getLedgerEntries is deployed.
func NewGetLedgerEntryHandler(logger *log.Entry, ledgerEntryReader db.LedgerEntryReader) jrpc2.Handler {
return handler.New(func(ctx context.Context, request GetLedgerEntryRequest) (GetLedgerEntryResponse, error) {
return NewHandler(func(ctx context.Context, request GetLedgerEntryRequest) (GetLedgerEntryResponse, error) {
var key xdr.LedgerKey
if err := xdr.SafeUnmarshalBase64(request.Key, &key); err != nil {
logger.WithError(err).WithField("request", request).
Expand Down
3 changes: 1 addition & 2 deletions cmd/soroban-rpc/internal/methods/get_network.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"

"github.com/creachadair/jrpc2"
"github.com/creachadair/jrpc2/handler"

"github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/daemon/interfaces"
)
Expand All @@ -20,7 +19,7 @@ type GetNetworkResponse struct {
// NewGetNetworkHandler returns a json rpc handler to for the getNetwork method
func NewGetNetworkHandler(daemon interfaces.Daemon, networkPassphrase, friendbotURL string) jrpc2.Handler {
coreClient := daemon.CoreClient()
return handler.New(func(ctx context.Context, request GetNetworkRequest) (GetNetworkResponse, error) {
return NewHandler(func(ctx context.Context, request GetNetworkRequest) (GetNetworkResponse, error) {
info, err := coreClient.Info(ctx)
if err != nil {
return GetNetworkResponse{}, (&jrpc2.Error{
Expand Down
3 changes: 1 addition & 2 deletions cmd/soroban-rpc/internal/methods/get_transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"fmt"

"github.com/creachadair/jrpc2"
"github.com/creachadair/jrpc2/handler"
"github.com/stellar/go/xdr"

"github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/transactions"
Expand Down Expand Up @@ -120,7 +119,7 @@ func GetTransaction(getter transactionGetter, request GetTransactionRequest) (Ge

// NewGetTransactionHandler returns a get transaction json rpc handler
func NewGetTransactionHandler(getter transactionGetter) jrpc2.Handler {
return handler.New(func(ctx context.Context, request GetTransactionRequest) (GetTransactionResponse, error) {
return NewHandler(func(ctx context.Context, request GetTransactionRequest) (GetTransactionResponse, error) {
return GetTransaction(getter, request)
})
}
17 changes: 17 additions & 0 deletions cmd/soroban-rpc/internal/methods/handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package methods

import (
"github.com/creachadair/jrpc2"
"github.com/creachadair/jrpc2/handler"
)

func NewHandler(fn any) jrpc2.Handler {
fi, err := handler.Check(fn)
if err != nil {
panic(err)
}
// explicitly disable array arguments since otherwise we cannot add
// new method arguments without breaking backwards compatibility with clients
fi.AllowArray(false)
return fi.Wrap()
}
60 changes: 60 additions & 0 deletions cmd/soroban-rpc/internal/methods/handler_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package methods

import (
"context"
"testing"

"github.com/creachadair/jrpc2"
"github.com/creachadair/jrpc2/handler"
"github.com/stretchr/testify/assert"
)

type Request struct {
Parameter string `json:"parameter"`
}

func TestNewHandlerNoArrayParameters(t *testing.T) {
callCount := 0
f := func(ctx context.Context, request Request) error {
callCount++
assert.Equal(t, "bar", request.Parameter)
return nil
}
objectRequest := `{
"jsonrpc": "2.0",
"id": 1,
"method": "foo",
"params": { "parameter": "bar" }
}`
requests, err := jrpc2.ParseRequests([]byte(objectRequest))
assert.NoError(t, err)
assert.Len(t, requests, 1)
finalObjectRequest := requests[0].ToRequest()

// object parameters should work with our handlers
customHandler := NewHandler(f)
_, err = customHandler(context.Background(), finalObjectRequest)
assert.NoError(t, err)
assert.Equal(t, 1, callCount)

arrayRequest := `{
"jsonrpc": "2.0",
"id": 1,
"method": "foo",
"params": ["bar"]
}`
requests, err = jrpc2.ParseRequests([]byte(arrayRequest))
assert.NoError(t, err)
assert.Len(t, requests, 1)
finalArrayRequest := requests[0].ToRequest()

// Array requests should work with the normal handler, but not with our handlers
stdHandler := handler.New(f)
_, err = stdHandler(context.Background(), finalArrayRequest)
assert.NoError(t, err)
assert.Equal(t, 2, callCount)

_, err = customHandler(context.Background(), finalArrayRequest)
assert.Error(t, err)
assert.Contains(t, err.Error(), "invalid parameters")
}
3 changes: 1 addition & 2 deletions cmd/soroban-rpc/internal/methods/health.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"time"

"github.com/creachadair/jrpc2"
"github.com/creachadair/jrpc2/handler"

"github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/transactions"
)
Expand All @@ -17,7 +16,7 @@ type HealthCheckResult struct {

// NewHealthCheck returns a health check json rpc handler
func NewHealthCheck(txStore *transactions.MemoryStore, maxHealthyLedgerLatency time.Duration) jrpc2.Handler {
return handler.New(func(ctx context.Context) (HealthCheckResult, error) {
return NewHandler(func(ctx context.Context) (HealthCheckResult, error) {
ledgerInfo := txStore.GetLatestLedger()
if ledgerInfo.Sequence < 1 {
return HealthCheckResult{}, jrpc2.Error{
Expand Down
3 changes: 1 addition & 2 deletions cmd/soroban-rpc/internal/methods/send_transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"encoding/hex"

"github.com/creachadair/jrpc2"
"github.com/creachadair/jrpc2/handler"
"github.com/stellar/go/network"
proto "github.com/stellar/go/protocols/stellarcore"
"github.com/stellar/go/support/log"
Expand Down Expand Up @@ -54,7 +53,7 @@ type LatestLedgerStore interface {
// NewSendTransactionHandler returns a submit transaction json rpc handler
func NewSendTransactionHandler(daemon interfaces.Daemon, logger *log.Entry, store LatestLedgerStore, passphrase string) jrpc2.Handler {
submitter := daemon.CoreClient()
return handler.New(func(ctx context.Context, request SendTransactionRequest) (SendTransactionResponse, error) {
return NewHandler(func(ctx context.Context, request SendTransactionRequest) (SendTransactionResponse, error) {
var envelope xdr.TransactionEnvelope
err := xdr.SafeUnmarshalBase64(request.Transaction, &envelope)
if err != nil {
Expand Down
3 changes: 1 addition & 2 deletions cmd/soroban-rpc/internal/methods/simulate_transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"fmt"

"github.com/creachadair/jrpc2"
"github.com/creachadair/jrpc2/handler"
"github.com/stellar/go/support/log"
"github.com/stellar/go/xdr"

Expand Down Expand Up @@ -53,7 +52,7 @@ type PreflightGetter interface {
// NewSimulateTransactionHandler returns a json rpc handler to run preflight simulations
func NewSimulateTransactionHandler(logger *log.Entry, ledgerEntryReader db.LedgerEntryReader, ledgerReader db.LedgerReader, getter PreflightGetter) jrpc2.Handler {

return handler.New(func(ctx context.Context, request SimulateTransactionRequest) SimulateTransactionResponse {
return NewHandler(func(ctx context.Context, request SimulateTransactionRequest) SimulateTransactionResponse {
var txEnvelope xdr.TransactionEnvelope
if err := xdr.SafeUnmarshalBase64(request.Transaction, &txEnvelope); err != nil {
logger.WithError(err).WithField("request", request).
Expand Down
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ toolchain go1.22.1
require (
github.com/Masterminds/squirrel v1.5.4
github.com/cenkalti/backoff/v4 v4.2.1
github.com/creachadair/jrpc2 v1.1.2
github.com/creachadair/jrpc2 v1.2.0
github.com/go-chi/chi v4.1.2+incompatible
github.com/go-git/go-git/v5 v5.9.0
github.com/mattn/go-sqlite3 v1.14.17
Expand Down Expand Up @@ -74,7 +74,7 @@ require (
github.com/aws/aws-sdk-go v1.45.27 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/creachadair/mds v0.3.0 // indirect
github.com/creachadair/mds v0.13.4 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
Expand Down Expand Up @@ -109,7 +109,7 @@ require (
golang.org/x/crypto v0.16.0 // indirect
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/sync v0.5.0 // indirect
golang.org/x/sync v0.6.0 // indirect
golang.org/x/sys v0.16.0 // indirect
golang.org/x/text v0.14.0 // indirect
google.golang.org/protobuf v1.32.0 // indirect
Expand Down
12 changes: 6 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,10 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creachadair/jrpc2 v1.1.2 h1:UOYMipEFYlwd5qmcvs9GZBurn3oXt1UDIX5JLjWWFzo=
github.com/creachadair/jrpc2 v1.1.2/go.mod h1:JcCe2Eny3lIvVwZLm92WXyU+tNUgTBWFCLMsfNkjEGk=
github.com/creachadair/mds v0.3.0 h1:uKbCKVtd3iOKVv3uviOm13fFNfe9qoCXJh1Vo7y3Kr0=
github.com/creachadair/mds v0.3.0/go.mod h1:4vrFYUzTXMJpMBU+OA292I6IUxKWCCfZkgXg+/kBZMo=
github.com/creachadair/jrpc2 v1.2.0 h1:SXr0OgnwM0X18P+HccJP0uT3KGSDk/BCSRlJBvE2bMY=
github.com/creachadair/jrpc2 v1.2.0/go.mod h1:66uKSdr6tR5ZeNvkIjDSbbVUtOv0UhjS/vcd8ECP7Iw=
github.com/creachadair/mds v0.13.4 h1:RgU0MhiVqkzp6/xtNWhK6Pw7tDeaVuGFtA0UA2RBYvY=
github.com/creachadair/mds v0.13.4/go.mod h1:4vrFYUzTXMJpMBU+OA292I6IUxKWCCfZkgXg+/kBZMo=
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand Down Expand Up @@ -543,8 +543,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand Down

0 comments on commit a3ba87e

Please sign in to comment.