Skip to content

Commit

Permalink
3.1 Denial of Service by Malicious Initiator (#130)
Browse files Browse the repository at this point in the history
* change rate limits and instance time to mitigate ddos

* fix instance test

* relax request limita to routes

* increase test time

* lint
  • Loading branch information
pavelkrolevets authored Oct 4, 2024
1 parent c1036e1 commit 691df4f
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 47 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/go-tasks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
run: go build -v ./...

- name: Test
run: go run gotest.tools/gotestsum@latest --format pkgname -- -timeout=3600s ./...
run: go run gotest.tools/gotestsum@latest --format pkgname -- -timeout=7200s ./...

- name: Critic
run: go install -v github.com/go-critic/go-critic/cmd/gocritic@latest && gocritic check ./...
Expand Down
26 changes: 13 additions & 13 deletions integration_test/reshare_bulk_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,19 +75,19 @@ func TestBulkReshareHappyFlows4Ops(t *testing.T) {
require.NoError(t, err)
resetFlags(RootCmd)
})
// t.Run("test 4 operators 100 validator bulk happy flow", func(t *testing.T) {
// args := []string{"init",
// "--validators", "100",
// "--operatorsInfo", string(operators),
// "--owner", "0xDCc846fA10C7CfCE9e6Eb37e06eD93b666cFC5E9",
// "--withdrawAddress", "0x81592c3de184a3e2c0dcb5a261bc107bfa91f494",
// "--operatorIDs", "11,22,33,44",
// "--nonce", "1"}
// RootCmd.SetArgs(args)
// err := RootCmd.Execute()
// require.NoError(t, err)
// resetFlags(RootCmd)
// })
t.Run("test 4 operators 100 validator bulk happy flow", func(t *testing.T) {
args := []string{"init",
"--validators", "100",
"--operatorsInfo", string(operators),
"--owner", "0xDCc846fA10C7CfCE9e6Eb37e06eD93b666cFC5E9",
"--withdrawAddress", "0x81592c3de184a3e2c0dcb5a261bc107bfa91f494",
"--operatorIDs", "11,22,33,44",
"--nonce", "1"}
RootCmd.SetArgs(args)
err := RootCmd.Execute()
require.NoError(t, err)
resetFlags(RootCmd)
})
// validate results
initCeremonies, err := os.ReadDir("./output")
require.NoError(t, err)
Expand Down
26 changes: 13 additions & 13 deletions integration_test/resign_bulk_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,19 +79,19 @@ func TestBulkResignHappyFlows4Ops(t *testing.T) {
require.NoError(t, err)
resetFlags(RootCmd)
})
// t.Run("test 4 operators 100 validator bulk happy flow", func(t *testing.T) {
// args := []string{"init",
// "--validators", "100",
// "--operatorsInfo", string(operators),
// "--owner", "0xDCc846fA10C7CfCE9e6Eb37e06eD93b666cFC5E9",
// "--withdrawAddress", "0x81592c3de184a3e2c0dcb5a261bc107bfa91f494",
// "--operatorIDs", "11,22,33,44",
// "--nonce", "1"}
// RootCmd.SetArgs(args)
// err := RootCmd.Execute()
// require.NoError(t, err)
// resetFlags(RootCmd)
// })
t.Run("test 4 operators 100 validator bulk happy flow", func(t *testing.T) {
args := []string{"init",
"--validators", "100",
"--operatorsInfo", string(operators),
"--owner", "0xDCc846fA10C7CfCE9e6Eb37e06eD93b666cFC5E9",
"--withdrawAddress", "0x81592c3de184a3e2c0dcb5a261bc107bfa91f494",
"--operatorIDs", "11,22,33,44",
"--nonce", "1"}
RootCmd.SetArgs(args)
err := RootCmd.Execute()
require.NoError(t, err)
resetFlags(RootCmd)
})
// validate results
initCeremonies, err := os.ReadDir("./output")
require.NoError(t, err)
Expand Down
11 changes: 8 additions & 3 deletions pkgs/operator/operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,14 @@ import (

// request limits
const (
generalLimit = 5000
routeLimit = 500
timePeriod = time.Minute
generalLimit = 5000
initRouteLimit = 200
resignRouteLimit = 200
reshareRouteLimit = 200
dkgRouteLimit = 500
healthCheckRouteLimit = 500
resultsRouteLimit = 500
timePeriod = time.Minute
)

// Server structure for operator to store http server and DKG ceremony instances
Expand Down
12 changes: 6 additions & 6 deletions pkgs/operator/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ import (
func RegisterRoutes(s *Server) {
s.Router.Use(rateLimit(s.Logger, generalLimit))

addRoute(s.Router, "POST", "/init", s.initHandler, rateLimit(s.Logger, routeLimit))
addRoute(s.Router, "POST", "/dkg", s.dkgHandler, rateLimit(s.Logger, routeLimit))
addRoute(s.Router, "GET", "/health_check", s.healthHandler, rateLimit(s.Logger, routeLimit))
addRoute(s.Router, "POST", "/results", s.resultsHandler, rateLimit(s.Logger, routeLimit))
addRoute(s.Router, "POST", "/resign", s.signedResignHandler, rateLimit(s.Logger, routeLimit))
addRoute(s.Router, "POST", "/reshare", s.signedReshareHandler, rateLimit(s.Logger, routeLimit))
addRoute(s.Router, "POST", "/init", s.initHandler, rateLimit(s.Logger, initRouteLimit))
addRoute(s.Router, "POST", "/dkg", s.dkgHandler, rateLimit(s.Logger, dkgRouteLimit))
addRoute(s.Router, "GET", "/health_check", s.healthHandler, rateLimit(s.Logger, healthCheckRouteLimit))
addRoute(s.Router, "POST", "/results", s.resultsHandler, rateLimit(s.Logger, resultsRouteLimit))
addRoute(s.Router, "POST", "/resign", s.signedResignHandler, rateLimit(s.Logger, resignRouteLimit))
addRoute(s.Router, "POST", "/reshare", s.signedReshareHandler, rateLimit(s.Logger, reshareRouteLimit))
}

// Add route with optional middleware
Expand Down
4 changes: 2 additions & 2 deletions pkgs/operator/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ import (
"github.com/ssvlabs/dkg-spec/eip1271"
)

const MaxInstances = 1024
const MaxInstanceTime = 5 * time.Minute
const MaxInstances = 1024 * 100
const MaxInstanceTime = 1 * time.Minute

// InstanceID each new DKG ceremony has a unique random ID that we can identify messages and be able to process them in parallel
type InstanceID [24]byte
Expand Down
31 changes: 22 additions & 9 deletions pkgs/operator/state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ import (
"github.com/bloxapp/ssv/utils/rsaencryption"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ssvlabs/ssv-dkg/pkgs/utils"
"github.com/ssvlabs/ssv-dkg/pkgs/wire"
"github.com/stretchr/testify/require"
"go.uber.org/zap"

spec "github.com/ssvlabs/dkg-spec"
spec_crypto "github.com/ssvlabs/dkg-spec/crypto"
"github.com/ssvlabs/dkg-spec/testing/stubs"
"github.com/ssvlabs/ssv-dkg/pkgs/dkg"
"github.com/ssvlabs/ssv-dkg/pkgs/utils"
"github.com/ssvlabs/ssv-dkg/pkgs/wire"
)

func singleOperatorKeys(t *testing.T) *rsa.PrivateKey {
Expand Down Expand Up @@ -155,24 +156,36 @@ func TestInitInstance(t *testing.T) {
require.Nil(t, resp2)

var tested = false

initiatorPubKey, err := spec_crypto.ParseRSAPublicKey(encPubKey)
require.NoError(t, err)
for i := 0; i < MaxInstances; i++ {
var reqIDx [24]byte
copy(reqIDx[:], fmt.Sprintf("testRequestID111111%v1", i)) // Just a sample value
respx, errx := swtch.State.InitInstance(reqIDx, initMessage, encPubKey, sig)
reqIDx := [24]byte{}
_, err := rand.Read(reqIDx[:]) // Just a sample value
require.NoError(t, err)
respx, errx := func(reqID [24]byte, initMsg *wire.Transport, initiatorPub, initiatorSignature []byte) ([]byte, error) {
if err := swtch.State.validateInstances(reqID); err != nil {
return nil, err
}
if err != nil {
return nil, fmt.Errorf("init: failed to create instance: %s", err.Error())
}
swtch.State.Mtx.Lock()
swtch.State.Instances[reqID] = &instWrapper{&dkg.LocalOwner{}, initiatorPubKey, make(chan []byte, 1)}
swtch.State.InstanceInitTime[reqID] = time.Now()
swtch.State.Mtx.Unlock()
return resp, nil
}(reqIDx, initMessage, encPubKey, sig)
if i == MaxInstances-1 {
require.Equal(t, errx, utils.ErrMaxInstances)
require.Nil(t, respx)
tested = true
break
}
require.NoError(t, errx)
require.NotNil(t, respx)
}

require.True(t, tested)

swtch.State.InstanceInitTime[reqID] = time.Now().Add(-6 * time.Minute)
swtch.State.InstanceInitTime[reqID] = time.Now().Add(-2 * time.Minute)

_, resp, err = swtch.State.CreateInstance(reqID, init.Operators, init, &priv.PublicKey)
require.NoError(t, err)
Expand Down

0 comments on commit 691df4f

Please sign in to comment.