CVE-2020-36568: Allocation of Resources Without Limits or Throttling (CWE-770)
value: Unsanitized input in the query parser in github.com/revel/revel before v1.0.0 allows remote attackers to cause resource exhaustion via memory allocation.
CWE description: The product allocates a reusable resource or group of resources on behalf of an actor without imposing any restrictions on the size or number of resources that can be allocated, in violation of the intended security policy for that actor.
CVSS v3 base score: 7.5
Published: 2022-12-27T22:15Z
Repository: https://github.com/revel/revel
Language: Go
Files changed: binder.go, binder_test.go
Commit date: 2019-03-09 11:21:44 +0800
Commit message: fix issue #1424

Diff: diff --git a/binder.go b/binder.go
index a42ed21..784e014 100644
--- a/binder.go
+++ b/binder.go
@@ -211,10 +211,12 @@ func bindSlice(params *Params, name string, typ reflect.Type) reflect.Value {
 	// Collect an array of slice elements with their indexes (and the max index).
 	maxIndex := -1
 	numNoIndex := 0
 	sliceValues := []sliceValue{}
 
+	maxIndexBound := Config.IntDefault("params.max_index", 4096)
+
 	// Factor out the common slice logic (between form values and files).
 	processElement := func(key string, vals []string, files []*multipart.FileHeader) {
 		if !strings.HasPrefix(key, name+"[") {
 			return
 		}
@@ -227,10 +229,15 @@ func bindSlice(params *Params, name string, typ reflect.Type) reflect.Value {
 		}
 		subKeyIndex := rightBracket + 1
 
 		// Handle the indexed case.
 		if index > -1 {
+			// Just ignore illegal index, fix issue #1424
+			if index > maxIndexBound {
+				binderLog.Error("Ignoring parameter for security reason", "index", index, "key", key)
+				return
+			}
 			if index > maxIndex {
 				maxIndex = index
 			}
 			sliceValues = append(sliceValues, sliceValue{
 				index: index,
diff --git a/binder_test.go b/binder_test.go
index 5ffd5cd..23749dd 100644
--- a/binder_test.go
+++ b/binder_test.go
@@ -5,10 +5,11 @@
 package revel
 
 import (
 	"encoding/json"
 	"fmt"
+	"github.com/revel/config"
 	"io"
 	"io/ioutil"
 	"os"
 	"reflect"
 	"sort"
@@ -96,10 +97,12 @@ var (
 		"invalidInt2":                    {""},
 		"invalidBool":                    {"xyz"},
 		"invalidArr":                     {"xyz"},
 		"int8-overflow":                  {"1024"},
 		"uint8-overflow":                 {"1024"},
+		"arrDoS[2]":                      {"2"},
+		"arrDoS[65535]":                  {"65535"},
 	}
 
 	testDate     = time.Date(1982, time.July, 9, 0, 0, 0, 0, time.UTC)
 	testDatetime = time.Date(1982, time.July, 9, 21, 30, 0, 0, time.UTC)
 )
@@ -166,10 +169,11 @@ var binderTestCases = map[string]interface{}{
 	"invalidBool":    true,
 	"invalidArr":     []int{},
 	"priv":           A{},
 	"int8-overflow":  int8(0),
 	"uint8-overflow": uint8(0),
+	"arrDoS":         []int{0, 0, 2},
 }
 
 // Types that files may be bound to, and a func that can read the content from
 // that type.
 // TODO: Is there any way to create a slice, given only the element Type?
@@ -211,10 +215,16 @@ func TestJsonBinder(t *testing.T) {
 
 func TestBinder(t *testing.T) {
 	// Reuse the mvc_test.go multipart request to test the binder.
 	params := &Params{}
 	c := NewTestController(nil, getMultipartRequest())
+	if Config == nil {
+		Config = config.NewContext()
+		defer func() {
+			Config = nil
+		}()
+	}
 	ParseParams(params, NewRequest(c.Request.In))
 	params.Values = ParamTestValues
 
 	// Values
 	for k, v := range binderTestCases {

Fixed code: 	maxIndexBound := Config.IntDefault("params.max_index", 4096)

			// Just ignore illegal index, fix issue #1424
			if index > maxIndexBound {
				binderLog.Error("Ignoring parameter for security reason", "index", index, "key", key)
				return
			}
	"github.com/revel/config"
		"arrDoS[2]":                      {"2"},
		"arrDoS[65535]":                  {"65535"},
	"arrDoS":         []int{0, 0, 2},
	if Config == nil {
		Config = config.NewContext()
		defer func() {
			Config = nil
		}()
	}