diff --git a/plugin/pkg/doh/doh.go b/plugin/pkg/doh/doh.go index e14c2ed28..f9f4e8df8 100644 --- a/plugin/pkg/doh/doh.go +++ b/plugin/pkg/doh/doh.go @@ -95,6 +95,9 @@ func requestToMsgPost(req *http.Request) (*dns.Msg, error) { return toMsg(req.Body) } +const maxDNSQuerySize = 65536 +const maxBase64Len = (maxDNSQuerySize*8 + 5) / 6 + // requestToMsgGet extract the dns message from the GET request. func requestToMsgGet(req *http.Request) (*dns.Msg, error) { values := req.URL.Query() @@ -105,11 +108,14 @@ func requestToMsgGet(req *http.Request) (*dns.Msg, error) { if len(b64) != 1 { return nil, fmt.Errorf("multiple 'dns' query values found") } + if len(b64[0]) > maxBase64Len { + return nil, fmt.Errorf("dns query too large") + } return base64ToMsg(b64[0]) } func toMsg(r io.ReadCloser) (*dns.Msg, error) { - buf, err := io.ReadAll(http.MaxBytesReader(nil, r, 65536)) + buf, err := io.ReadAll(http.MaxBytesReader(nil, r, maxDNSQuerySize)) if err != nil { return nil, err } diff --git a/plugin/pkg/doh/doh_test.go b/plugin/pkg/doh/doh_test.go index 047d0136d..2bdfd2d15 100644 --- a/plugin/pkg/doh/doh_test.go +++ b/plugin/pkg/doh/doh_test.go @@ -44,3 +44,26 @@ func TestDoH(t *testing.T) { }) } } + +func TestDoHGETRejectsOversizedDNSQuery(t *testing.T) { + // Exceeding max size 65536 + raw := make([]byte, 65536+1) + b64 := b64Enc.EncodeToString(raw) + + req, err := http.NewRequest( + http.MethodGet, + "https://example.org"+Path+"?dns="+b64, + nil, + ) + if err != nil { + t.Fatalf("failed to build request: %v", err) + } + + _, err = RequestToMsg(req) + if err == nil { + t.Fatalf("expected oversized GET dns query to be rejected") + } + if err.Error() != "dns query too large" { + t.Fatalf("expected %q, got %v", "dns query too large", err) + } +}