mirror of
https://github.com/caddyserver/caddy.git
synced 2026-11-11 19:37:55 +00:00
Reject opaque HTTP request targets before either normal or error routes can interpret them. Clear URL.Opaque defensively on proxy clones. Verify HTTP/1 parsing, path authentication, supported target forms and outbound serialization without contacting an upstream. Addresses scan report e17d2fcd-d50c-4d68-82d1-96519a437a24. Code written by GitHub Copilot (GPT-6.1 Sol, Claude Opus 5.5); reviewed by mholt. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
44 lines
1.1 KiB
Go
44 lines
1.1 KiB
Go
package reverseproxy
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"net/http"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestCloneRequestClearsOpaqueTarget(t *testing.T) {
|
|
for _, tc := range []struct {
|
|
target, want string
|
|
}{
|
|
{"/public?x=1", "/public?x=1"},
|
|
{"http://public.example/public?x=1", "/public?x=1"},
|
|
{"http:http://private.example/secret", "/"},
|
|
} {
|
|
t.Run(tc.target, func(t *testing.T) {
|
|
original, err := http.ReadRequest(bufio.NewReader(strings.NewReader(
|
|
"GET " + tc.target + " HTTP/1.1\r\nHost: public.example\r\n\r\n")))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer original.Body.Close()
|
|
originalURL := *original.URL
|
|
cloned := cloneRequest(original)
|
|
cloned.URL.Scheme = "http"
|
|
cloned.URL.Host = "selected-upstream.example"
|
|
var wire bytes.Buffer
|
|
if err := cloned.Write(&wire); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
want := "GET " + tc.want + " HTTP/1.1\r\n"
|
|
if !strings.HasPrefix(wire.String(), want) {
|
|
t.Fatalf("outbound target = %q, want prefix %q", wire.String(), want)
|
|
}
|
|
if *original.URL != originalURL {
|
|
t.Fatal("original request URL was mutated")
|
|
}
|
|
})
|
|
}
|
|
}
|