Skip to content

Commit

Permalink
rpc: check that "version" is "2.0" in request objects (#25570)
Browse files Browse the repository at this point in the history
The JSON-RPC spec requires the "version" field to be exactly "2.0",
so we should verify that. This change is not backwards-compatible with
sloppy client implementations, but I decided to go ahead with it anyway
because the failure will be caught via the returned error.
  • Loading branch information
dbadoy authored Sep 2, 2022
1 parent 90711ef commit 38e002f
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 4 deletions.
10 changes: 7 additions & 3 deletions rpc/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,21 +58,25 @@ type jsonrpcMessage struct {
}

func (msg *jsonrpcMessage) isNotification() bool {
return msg.ID == nil && msg.Method != ""
return msg.hasValidVersion() && msg.ID == nil && msg.Method != ""
}

func (msg *jsonrpcMessage) isCall() bool {
return msg.hasValidID() && msg.Method != ""
return msg.hasValidVersion() && msg.hasValidID() && msg.Method != ""
}

func (msg *jsonrpcMessage) isResponse() bool {
return msg.hasValidID() && msg.Method == "" && msg.Params == nil && (msg.Result != nil || msg.Error != nil)
return msg.hasValidVersion() && msg.hasValidID() && msg.Method == "" && msg.Params == nil && (msg.Result != nil || msg.Error != nil)
}

func (msg *jsonrpcMessage) hasValidID() bool {
return len(msg.ID) > 0 && msg.ID[0] != '{' && msg.ID[0] != '['
}

func (msg *jsonrpcMessage) hasValidVersion() bool {
return msg.Version == vsn
}

func (msg *jsonrpcMessage) isSubscribe() bool {
return strings.HasSuffix(msg.Method, subscribeMethodSuffix)
}
Expand Down
2 changes: 1 addition & 1 deletion rpc/subscription_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func TestSubscriptions(t *testing.T) {
request := map[string]interface{}{
"id": i,
"method": fmt.Sprintf("%s_subscribe", namespace),
"version": "2.0",
"jsonrpc": "2.0",
"params": []interface{}{"someSubscription", notificationCount, i},
}
if err := out.Encode(&request); err != nil {
Expand Down
19 changes: 19 additions & 0 deletions rpc/testdata/invalid-badversion.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// This test checks processing of messages with invalid Version.

--> {"jsonrpc":"2.0","id":1,"method":"test_echo","params":["x", 3]}
<-- {"jsonrpc":"2.0","id":1,"result":{"String":"x","Int":3,"Args":null}}

--> {"jsonrpc":"2.1","id":1,"method":"test_echo","params":["x", 3]}
<-- {"jsonrpc":"2.0","id":1,"error":{"code":-32600,"message":"invalid request"}}

--> {"jsonrpc":"go-ethereum","id":1,"method":"test_echo","params":["x", 3]}
<-- {"jsonrpc":"2.0","id":1,"error":{"code":-32600,"message":"invalid request"}}

--> {"jsonrpc":1,"id":1,"method":"test_echo","params":["x", 3]}
<-- {"jsonrpc":"2.0","id":1,"error":{"code":-32600,"message":"invalid request"}}

--> {"jsonrpc":2.0,"id":1,"method":"test_echo","params":["x", 3]}
<-- {"jsonrpc":"2.0","id":1,"error":{"code":-32600,"message":"invalid request"}}

--> {"id":1,"method":"test_echo","params":["x", 3]}
<-- {"jsonrpc":"2.0","id":1,"error":{"code":-32600,"message":"invalid request"}}

0 comments on commit 38e002f

Please sign in to comment.