mirror of
https://github.com/containous/traefik.git
synced 2024-10-26 08:55:09 +03:00
Deny request with fragment in URL path
Co-authored-by: Kevin Pollet <pollet.kevin@gmail.com>
This commit is contained in:
parent
cd326654a7
commit
12e50e20e6
@ -1480,3 +1480,31 @@ func (s *SimpleSuite) TestEncodeSemicolons(c *check.C) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SimpleSuite) TestDenyFragment(c *check.C) {
|
||||
s.createComposeProject(c, "base")
|
||||
|
||||
s.composeUp(c)
|
||||
defer s.composeDown(c)
|
||||
|
||||
cmd, output := s.traefikCmd(withConfigFile("fixtures/simple_default.toml"))
|
||||
defer output(c)
|
||||
|
||||
err := cmd.Start()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer s.killCmd(cmd)
|
||||
|
||||
// Expected a 404 as we did not configure anything
|
||||
err = try.GetRequest("http://127.0.0.1:8000/", 1*time.Second, try.StatusCodeIs(http.StatusNotFound))
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
conn, err := net.Dial("tcp", "127.0.0.1:8000")
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
_, err = conn.Write([]byte("GET /#/?bar=toto;boo=titi HTTP/1.1\nHost: other.localhost\n\n"))
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
resp, err := http.ReadResponse(bufio.NewReader(conn), nil)
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(resp.StatusCode, checker.Equals, http.StatusBadRequest)
|
||||
}
|
||||
|
@ -535,6 +535,7 @@ func createHTTPServer(ctx context.Context, ln net.Listener, configuration *stati
|
||||
return nil, err
|
||||
}
|
||||
|
||||
handler = denyFragment(handler)
|
||||
if configuration.HTTP.EncodeQuerySemicolons {
|
||||
handler = encodeQuerySemicolons(handler)
|
||||
} else {
|
||||
@ -620,3 +621,20 @@ func encodeQuerySemicolons(h http.Handler) http.Handler {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// When go receives an HTTP request, it assumes the absence of fragment URL.
|
||||
// However, it is still possible to send a fragment in the request.
|
||||
// In this case, Traefik will encode the '#' character, altering the request's intended meaning.
|
||||
// To avoid this behavior, the following function rejects requests that include a fragment in the URL.
|
||||
func denyFragment(h http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
if strings.Contains(req.URL.RawPath, "#") {
|
||||
log.WithoutContext().Debugf("Rejecting request because it contains a fragment in the URL path: %s", req.URL.RawPath)
|
||||
rw.WriteHeader(http.StatusBadRequest)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
h.ServeHTTP(rw, req)
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user