fix: block arbitrary file index (#2497)

diff --git a/api/test/e2e/gzip/gzip_suite_test.go b/api/internal/filter/invalid_request.go
similarity index 66%
copy from api/test/e2e/gzip/gzip_suite_test.go
copy to api/internal/filter/invalid_request.go
index 13380cf..8c1ebc5 100644
--- a/api/test/e2e/gzip/gzip_suite_test.go
+++ b/api/internal/filter/invalid_request.go
@@ -14,16 +14,28 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package gzip_test
+package filter
 
 import (
-	"testing"
+	"net/url"
+	"strings"
 
-	. "github.com/onsi/ginkgo"
-	. "github.com/onsi/gomega"
+	"github.com/gin-gonic/gin"
 )
 
-func TestGzip(t *testing.T) {
-	RegisterFailHandler(Fail)
-	RunSpecs(t, "gzip suite")
+// InvalidRequest provides a filtering mechanism for illegitimate requests
+func InvalidRequest() gin.HandlerFunc {
+	return func(c *gin.Context) {
+		if !checkURL(c.Request.URL) {
+			c.AbortWithStatus(403)
+		}
+		c.Next()
+	}
+}
+
+func checkURL(url *url.URL) bool {
+	if strings.Contains(url.Path, "..") {
+		return false
+	}
+	return true
 }
diff --git a/api/test/e2e/gzip/gzip_suite_test.go b/api/internal/filter/invalid_request_test.go
similarity index 71%
copy from api/test/e2e/gzip/gzip_suite_test.go
copy to api/internal/filter/invalid_request_test.go
index 13380cf..986a791 100644
--- a/api/test/e2e/gzip/gzip_suite_test.go
+++ b/api/internal/filter/invalid_request_test.go
@@ -14,16 +14,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package gzip_test
+package filter
 
 import (
+	"net/url"
 	"testing"
 
-	. "github.com/onsi/ginkgo"
-	. "github.com/onsi/gomega"
+	"github.com/stretchr/testify/assert"
 )
 
-func TestGzip(t *testing.T) {
-	RegisterFailHandler(Fail)
-	RunSpecs(t, "gzip suite")
+func TestURLCheck_double_dot(t *testing.T) {
+	assert.Equal(t, false, checkURL(&url.URL{Path: "../../../etc/hosts"}))
+	assert.Equal(t, false, checkURL(&url.URL{Path: "/../../../etc/hosts"}))
+	assert.Equal(t, true, checkURL(&url.URL{Path: "/etc/hosts"}))
 }
diff --git a/api/internal/route.go b/api/internal/route.go
index 7eddc9c..6f7e136 100644
--- a/api/internal/route.go
+++ b/api/internal/route.go
@@ -57,8 +57,11 @@
 	}
 	r := gin.New()
 	logger := log.GetLogger(log.AccessLog)
-	r.Use(gzip.Gzip(gzip.DefaultCompression))
-	r.Use(filter.CORS(), filter.RequestId(), filter.IPFilter(), filter.RequestLogHandler(logger), filter.SchemaCheck(), filter.RecoverHandler(), filter.Authentication())
+	// security
+	r.Use(filter.RequestLogHandler(logger), filter.IPFilter(), filter.InvalidRequest(), filter.Authentication())
+
+	// misc
+	r.Use(gzip.Gzip(gzip.DefaultCompression), filter.CORS(), filter.RequestId(), filter.SchemaCheck(), filter.RecoverHandler())
 	r.Use(static.Serve("/", static.LocalFile(filepath.Join(conf.WorkDir, conf.WebDir), false)))
 	r.NoRoute(func(c *gin.Context) {
 		c.File(fmt.Sprintf("%s/index.html", filepath.Join(conf.WorkDir, conf.WebDir)))
diff --git a/api/test/e2e/gzip/gzip_test.go b/api/test/e2e/middlewares/gzip_test.go
similarity index 90%
rename from api/test/e2e/gzip/gzip_test.go
rename to api/test/e2e/middlewares/gzip_test.go
index fbacc27..f346f10 100644
--- a/api/test/e2e/gzip/gzip_test.go
+++ b/api/test/e2e/middlewares/gzip_test.go
@@ -14,18 +14,18 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package gzip
+package middlewares_test
 
 import (
 	"net/http"
 
-	"github.com/onsi/ginkgo"
+	. "github.com/onsi/ginkgo"
 
 	"github.com/apisix/manager-api/test/e2e/base"
 )
 
-var _ = ginkgo.Describe("Gzip enable", func() {
-	ginkgo.It("get index.html", func() {
+var _ = Describe("Gzip enable", func() {
+	It("get index.html", func() {
 		base.RunTestCase(base.HttpTestCase{
 			Object:        base.ManagerApiExpect(),
 			Method:        http.MethodGet,
diff --git a/api/test/e2e/gzip/gzip_test.go b/api/test/e2e/middlewares/invalid_request_test.go
similarity index 63%
copy from api/test/e2e/gzip/gzip_test.go
copy to api/test/e2e/middlewares/invalid_request_test.go
index fbacc27..7b6cf43 100644
--- a/api/test/e2e/gzip/gzip_test.go
+++ b/api/test/e2e/middlewares/invalid_request_test.go
@@ -14,24 +14,29 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package gzip
+package middlewares_test
 
 import (
 	"net/http"
 
-	"github.com/onsi/ginkgo"
+	. "github.com/onsi/ginkgo"
 
 	"github.com/apisix/manager-api/test/e2e/base"
 )
 
-var _ = ginkgo.Describe("Gzip enable", func() {
-	ginkgo.It("get index.html", func() {
+var _ = Describe("Invalid Request", func() {
+	It("double dot in URL path (arbitrary file index)", func() {
 		base.RunTestCase(base.HttpTestCase{
-			Object:        base.ManagerApiExpect(),
-			Method:        http.MethodGet,
-			Path:          "/",
-			Headers:       map[string]string{"Accept-Encoding": "gzip, deflate, br"},
-			ExpectHeaders: map[string]string{"Content-Encoding": "gzip"},
+			Object:       base.ManagerApiExpect(),
+			Method:       http.MethodGet,
+			Path:         "/../../../../etc/hosts",
+			ExpectStatus: http.StatusForbidden,
+		})
+		base.RunTestCase(base.HttpTestCase{
+			Object:       base.ManagerApiExpect(),
+			Method:       http.MethodGet,
+			Path:         "/.%2e/%2e%2e/../etc/hosts",
+			ExpectStatus: http.StatusForbidden,
 		})
 	})
 })
diff --git a/api/test/e2e/gzip/gzip_suite_test.go b/api/test/e2e/middlewares/middlewares_suite_test.go
similarity index 89%
rename from api/test/e2e/gzip/gzip_suite_test.go
rename to api/test/e2e/middlewares/middlewares_suite_test.go
index 13380cf..0bdcebb 100644
--- a/api/test/e2e/gzip/gzip_suite_test.go
+++ b/api/test/e2e/middlewares/middlewares_suite_test.go
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package gzip_test
+package middlewares_test
 
 import (
 	"testing"
@@ -23,7 +23,7 @@
 	. "github.com/onsi/gomega"
 )
 
-func TestGzip(t *testing.T) {
+func TestMiddlewares(t *testing.T) {
 	RegisterFailHandler(Fail)
-	RunSpecs(t, "gzip suite")
+	RunSpecs(t, "Middlewares Suite")
 }