1
0
Fork 0

Fix deny encoded characters

Co-authored-by: Kevin Pollet <pollet.kevin@gmail.com>
This commit is contained in:
Romain 2025-12-23 16:00:05 +01:00 committed by GitHub
parent 8ebab1b243
commit 90ce858347
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
21 changed files with 427 additions and 300 deletions

View file

@ -0,0 +1,34 @@
[global]
checkNewVersion = false
sendAnonymousUsage = false
[log]
level = "DEBUG"
[entryPoints]
[entryPoints.strict]
address = ":8000"
# Default: no encoded characters allowed
[entryPoints.permissive]
address = ":8001"
[entryPoints.permissive.http.encodedCharacters]
allowEncodedSlash = true
[api]
insecure = true
[providers.file]
filename = "{{ .SelfFilename }}"
## dynamic configuration ##
[http.routers]
[http.routers.sameRouter]
service = "service1"
rule = "Host(`test.localhost`)"
[http.services]
[http.services.service1.loadBalancer]
[[http.services.service1.loadBalancer.servers]]
url = "{{ .Server1 }}"

View file

@ -1481,3 +1481,72 @@ func (s *SimpleSuite) TestSanitizePath() {
}
}
}
// TestEncodedCharactersDifferentEntryPoints verifies that router handler caching does not interfere with
// per-entry-point encoded characters configuration.
// The same router should behave differently on different entry points.
func (s *SimpleSuite) TestEncodedCharactersDifferentEntryPoints() {
s.createComposeProject("base")
s.composeUp()
defer s.composeDown()
whoami1URL := "http://" + net.JoinHostPort(s.getComposeServiceIP("whoami1"), "80")
file := s.adaptFile("fixtures/simple_encoded_chars.toml", struct {
Server1 string
}{whoami1URL})
s.traefikCmd(withConfigFile(file))
err := try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("Host(`test.localhost`)"))
require.NoError(s.T(), err)
testCases := []struct {
desc string
request string
target string
expected int
}{
{
desc: "Encoded slash should be REJECTED on strict entry point",
request: "GET /path%2Fwith%2Fslash HTTP/1.1\r\nHost: test.localhost\r\n\r\n",
target: "127.0.0.1:8000", // strict entry point
expected: http.StatusBadRequest,
},
{
desc: "Encoded slash should be ALLOWED on permissive entry point",
request: "GET /path%2Fwith%2Fslash HTTP/1.1\r\nHost: test.localhost\r\n\r\n",
target: "127.0.0.1:8001", // permissive entry point
expected: http.StatusOK,
},
{
desc: "Regular path should work on strict entry point",
request: "GET /regular/path HTTP/1.1\r\nHost: test.localhost\r\n\r\n",
target: "127.0.0.1:8000",
expected: http.StatusOK,
},
{
desc: "Regular path should work on permissive entry point",
request: "GET /regular/path HTTP/1.1\r\nHost: test.localhost\r\n\r\n",
target: "127.0.0.1:8001",
expected: http.StatusOK,
},
}
for _, test := range testCases {
conn, err := net.Dial("tcp", test.target)
require.NoError(s.T(), err)
_, err = conn.Write([]byte(test.request))
require.NoError(s.T(), err)
resp, err := http.ReadResponse(bufio.NewReader(conn), nil)
require.NoError(s.T(), err)
assert.Equalf(s.T(), test.expected, resp.StatusCode, "%s failed with %d instead of %d", test.desc, resp.StatusCode, test.expected)
err = conn.Close()
require.NoError(s.T(), err)
}
}