Browse Source

Fix DoS attack vulnerability in CommandSwitchAccountFactory

Shelikhoo 3 years ago
parent
commit
6fb5c887b2
2 changed files with 22 additions and 1 deletions
  1. 1 1
      proxy/vmess/encoding/commands.go
  2. 21 0
      proxy/vmess/encoding/commands_test.go

+ 1 - 1
proxy/vmess/encoding/commands.go

@@ -139,7 +139,7 @@ func (f *CommandSwitchAccountFactory) Unmarshal(data []byte) (interface{}, error
 	}
 	cmd.Level = uint32(data[levelStart])
 	timeStart := levelStart + 1
-	if len(data) < timeStart {
+	if len(data) < timeStart+1 {
 		return nil, newError("insufficient length.")
 	}
 	cmd.ValidMin = data[timeStart]

+ 21 - 0
proxy/vmess/encoding/commands_test.go

@@ -4,6 +4,7 @@ import (
 	"testing"
 
 	"github.com/google/go-cmp/cmp"
+	"github.com/stretchr/testify/assert"
 
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common/buf"
@@ -35,3 +36,23 @@ func TestSwitchAccount(t *testing.T) {
 		t.Error(r)
 	}
 }
+
+func TestSwitchAccountBugOffByOne(t *testing.T) {
+	sa := &protocol.CommandSwitchAccount{
+		Port:     1234,
+		ID:       uuid.New(),
+		AlterIds: 1024,
+		Level:    128,
+		ValidMin: 16,
+	}
+
+	buffer := buf.New()
+	csaf := CommandSwitchAccountFactory{}
+	common.Must(csaf.Marshal(sa, buffer))
+
+	Payload := buffer.Bytes()
+
+	cmd, err := csaf.Unmarshal(Payload[:len(Payload)-1])
+	assert.Error(t, err)
+	assert.Nil(t, cmd)
+}