fix: clean X-Forwarded-Prefix header for the dashboard.

This commit is contained in:
Ludovic Fernandez
2020-07-28 10:10:03 +02:00
committed by GitHub
parent cb6b94ff40
commit cfa04c300c
2 changed files with 77 additions and 4 deletions

View File

@@ -2,6 +2,7 @@ package api
import (
"net/http"
"net/url"
"github.com/containous/mux"
"github.com/containous/traefik/log"
@@ -23,17 +24,35 @@ func (g DashboardHandler) AddRoutes(router *mux.Router) {
// Expose dashboard
router.Methods(http.MethodGet).
Path("/").
HandlerFunc(func(response http.ResponseWriter, request *http.Request) {
http.Redirect(response, request, request.Header.Get("X-Forwarded-Prefix")+"/dashboard/", 302)
HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
http.Redirect(resp, req, safePrefix(req)+"/dashboard/", 302)
})
router.Methods(http.MethodGet).
Path("/dashboard/status").
HandlerFunc(func(response http.ResponseWriter, request *http.Request) {
http.Redirect(response, request, "/dashboard/", 302)
HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
http.Redirect(resp, req, "/dashboard/", 302)
})
router.Methods(http.MethodGet).
PathPrefix("/dashboard/").
Handler(http.StripPrefix("/dashboard/", http.FileServer(g.Assets)))
}
func safePrefix(req *http.Request) string {
prefix := req.Header.Get("X-Forwarded-Prefix")
if prefix == "" {
return ""
}
parse, err := url.Parse(prefix)
if err != nil {
return ""
}
if parse.Host != "" {
return ""
}
return parse.Path
}

54
api/dashboard_test.go Normal file
View File

@@ -0,0 +1,54 @@
package api
import (
"net/http"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func Test_safePrefix(t *testing.T) {
testCases := []struct {
desc string
value string
expected string
}{
{
desc: "host",
value: "https://example.com",
expected: "",
},
{
desc: "host with path",
value: "https://example.com/foo/bar?test",
expected: "",
},
{
desc: "path",
value: "/foo/bar",
expected: "/foo/bar",
},
{
desc: "path without leading slash",
value: "foo/bar",
expected: "foo/bar",
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
req, err := http.NewRequest(http.MethodGet, "http://localhost", nil)
require.NoError(t, err)
req.Header.Set("X-Forwarded-Prefix", test.value)
prefix := safePrefix(req)
assert.Equal(t, test.expected, prefix)
})
}
}