Skip to content

Commit

Permalink
Add sequence number DoS test
Browse files Browse the repository at this point in the history
  • Loading branch information
gammazero committed Aug 23, 2023
1 parent ca23a44 commit 7774ca0
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 1 deletion.
1 change: 0 additions & 1 deletion chain/sub/incoming.go
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,6 @@ func (v *IndexerMessageValidator) Validate(ctx context.Context, pid peer.ID, msg

msgCid := idxrMsg.Cid

var msgInfo *peerMsgInfo
msgInfo, cached := v.peerCache.Get(minerAddr)
if !cached {
msgInfo = &peerMsgInfo{}
Expand Down
122 changes: 122 additions & 0 deletions chain/sub/incoming_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ import (
"context"
"testing"

"github.com/filecoin-project/lotus/api"
"github.com/golang/mock/gomock"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid"
"github.com/ipni/go-libipni/announce/message"
pubsub "github.com/libp2p/go-libp2p-pubsub"
pb "github.com/libp2p/go-libp2p-pubsub/pb"
"github.com/libp2p/go-libp2p/core/crypto"
"github.com/libp2p/go-libp2p/core/peer"

"github.com/filecoin-project/go-address"
Expand Down Expand Up @@ -134,3 +136,123 @@ func TestIndexerMessageValidator_Validate(t *testing.T) {
})
}
}

func TestIdxValidator(t *testing.T) {
validCid, err := cid.Decode("QmbpDgg5kRLDgMxS8vPKNFXEcA6D5MC4CkuUdSWDVtHPGK")
if err != nil {
t.Fatal(err)
}

addr, err := address.NewFromString("f01024")
if err != nil {
t.Fatal(err)
}

buf1, err := addr.MarshalBinary()
if err != nil {
t.Fatal(err)
}

selfPID := "12D3KooWQiCbqEStCkdqUvr69gQsrp9urYJZUCkzsQXia7mbqbFW"
senderPID := "12D3KooWE8yt84RVwW3sFcd6WMjbUdWrZer2YtT4dmtj3dHdahSZ"
extraData := buf1

mc := gomock.NewController(t)
node := mocks.NewMockFullNode(mc)
node.EXPECT().ChainHead(gomock.Any()).Return(nil, nil).AnyTimes()

subject := NewIndexerMessageValidator(peer.ID(selfPID), node, node)
message := message.Message{
Cid: validCid,
Addrs: nil,
ExtraData: extraData,
}
buf := bytes.NewBuffer(nil)
if err := message.MarshalCBOR(buf); err != nil {
t.Fatal(err)
}

topic := "topic"

privk, _, err := crypto.GenerateKeyPair(crypto.RSA, 2048)
if err != nil {
t.Fatal(err)
}
id, err := peer.IDFromPublicKey(privk.GetPublic())
if err != nil {
t.Fatal(err)
}

node.EXPECT().StateMinerInfo(gomock.Any(), gomock.Any(), gomock.Any()).Return(api.MinerInfo{PeerId: &id}, nil).AnyTimes()

pbm := &pb.Message{
Data: buf.Bytes(),
Topic: &topic,
From: []byte(id),
Seqno: []byte{1, 1, 1, 1, 2, 2, 2, 2},
}
validate := subject.Validate(context.Background(), peer.ID(senderPID), &pubsub.Message{
Message: pbm,
ReceivedFrom: peer.ID("f01024"), // peer.ID(senderPID),
ValidatorData: nil,
})
if validate != pubsub.ValidationAccept {
t.Error("Expected to receive ValidationAccept")
}
msgInfo, cached := subject.peerCache.Get(addr)
if !cached {
t.Fatal("Message info should be in cache")
}
seqno := msgInfo.lastSeqno
msgInfo.rateLimit = nil // prevent interference from rate limiting

t.Log("Sending DoS msg")
privk, _, err = crypto.GenerateKeyPair(crypto.RSA, 2048)
if err != nil {
t.Fatal(err)
}
id2, err := peer.IDFromPublicKey(privk.GetPublic())
if err != nil {
t.Fatal(err)
}
pbm = &pb.Message{
Data: buf.Bytes(),
Topic: &topic,
From: []byte(id2),
Seqno: []byte{255, 255, 255, 255, 255, 255, 255, 255},
}
validate = subject.Validate(context.Background(), peer.ID(senderPID), &pubsub.Message{
Message: pbm,
ReceivedFrom: peer.ID(senderPID),
ValidatorData: nil,
})
if validate != pubsub.ValidationReject {
t.Error("Expected to get ValidationReject")
}
msgInfo, cached = subject.peerCache.Get(addr)
if !cached {
t.Fatal("Message info should be in cache")
}
msgInfo.rateLimit = nil // prevent interference from rate limiting

// Check if DoS is possible.
if msgInfo.lastSeqno != seqno {
t.Fatal("Sequence number should not have been updated")
}

t.Log("Sending another valid message from miner...")
pbm = &pb.Message{
Data: buf.Bytes(),
Topic: &topic,
From: []byte(id),
Seqno: []byte{1, 1, 1, 1, 2, 2, 2, 3},
}
validate = subject.Validate(context.Background(), peer.ID(senderPID), &pubsub.Message{
Message: pbm,
ReceivedFrom: peer.ID("f01024"), // peer.ID(senderPID),
ValidatorData: nil,
})
if validate != pubsub.ValidationAccept {
t.Fatal("Did not receive ValidationAccept")
}
}

0 comments on commit 7774ca0

Please sign in to comment.