@marcel91200 / caddy Mirror · read-only / commits / 04a14ee3
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 13, 16:45 UTC

caddyhttp: Make query matcher more efficient

Only parse query string once

Matthew Holt committed Jul 13, 2022 at 12:20 UTC 04a14ee37ac6192d734518fa9082d6eb93971bc6
1 file changed +17 -1
modules/caddyhttp/matchers.go
+17 -1
@@ -103,6 +103,9 @@ type (
103 // "query": ["*"]
104 // }
105 // ```
106 + //
107 + // Invalid query strings, including those with bad escapings or illegal characters
108 + // like semicolons, will fail to parse and thus fail to match.
109 MatchQuery url.Values
110
111 // MatchHeader matches requests by header fields. The key is the field
@@ -625,9 +628,22 @@ func (m *MatchQuery) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
628 // Match returns true if r matches m. An empty m matches an empty query string.
629 func (m MatchQuery) Match(r *http.Request) bool {
630 repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
631 +
632 + // parse query string just once, for efficiency
633 + parsed, err := url.ParseQuery(r.URL.RawQuery)
634 + if err != nil {
635 + // Illegal query string. Likely bad escape sequence or syntax.
636 + // Note that semicolons in query string have a controversial history. Summaries:
637 + // - https://github.com/golang/go/issues/50034
638 + // - https://github.com/golang/go/issues/25192
639 + // W3C recommendations are flawed and ambiguous, and different servers handle semicolons differently.
640 + // Filippo Valsorda rightly wrote: "Relying on parser alignment for security is doomed."
641 + return false
642 + }
643 +
644 for param, vals := range m {
645 param = repl.ReplaceAll(param, "")
630 - paramVal, found := r.URL.Query()[param]
646 + paramVal, found := parsed[param]
647 if found {
648 for _, v := range vals {
649 v = repl.ReplaceAll(v, "")