mirror of
https://github.com/golang/go.git
synced 2026-06-28 03:40:37 +00:00
net/http/httputil: reencode queries with many parameters in proxy
When ReverseProxy forwards a request containing more than urlmaxqueryparams (GODEBUG) query parameters, reencode the outbound query parameters. Avoids potential smuggling of query parameters, where the sender sends many query parameters, the user's Rewrite hook fails to observe those parameters due to the limit being exceeded, and the request is forwarded with the full set of parameters. Fixes #78948 Fixes CVE-2026-39825 Change-Id: I691be7899c4b6208bf61f6b78dacfdf56a6a6964 Reviewed-on: https://go-review.googlesource.com/c/go/+/770541 Reviewed-by: Nicholas Husin <nsh@golang.org> Reviewed-by: Nicholas Husin <husin@google.com> Auto-Submit: Damien Neil <dneil@google.com> LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
parent
1f5c165a81
commit
6795bb3317
3 changed files with 21 additions and 0 deletions
|
|
@ -10,6 +10,7 @@ import (
|
|||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"internal/godebug"
|
||||
"io"
|
||||
"log"
|
||||
"mime"
|
||||
|
|
@ -922,11 +923,24 @@ func (c switchProtocolCopier) copyToBackend(errc chan<- error) {
|
|||
errc <- errCopyDone
|
||||
}
|
||||
|
||||
var urlmaxqueryparams = godebug.New("urlmaxqueryparams")
|
||||
|
||||
// Keep this in sync with net/url.
|
||||
const defaultMaxParams = 10000
|
||||
|
||||
func cleanQueryParams(s string) string {
|
||||
reencode := func(s string) string {
|
||||
v, _ := url.ParseQuery(s)
|
||||
return v.Encode()
|
||||
}
|
||||
if urlmaxqueryparams.Value() != "" {
|
||||
// Always reencode when a non-default urlmaxqueryparams is set.
|
||||
return reencode(s)
|
||||
}
|
||||
if numParams := strings.Count(s, "&") + 1; numParams > defaultMaxParams {
|
||||
// Too many query parameters.
|
||||
return reencode(s)
|
||||
}
|
||||
for i := 0; i < len(s); {
|
||||
switch s[i] {
|
||||
case ';':
|
||||
|
|
|
|||
|
|
@ -2087,6 +2087,12 @@ func testReverseProxyQueryParameterSmuggling(t *testing.T, wantCleanQuery bool,
|
|||
}, {
|
||||
rawQuery: "a=1&a=%zz&b=3",
|
||||
cleanQuery: "a=1&b=3",
|
||||
}, {
|
||||
rawQuery: "a=%zz",
|
||||
cleanQuery: "",
|
||||
}, {
|
||||
rawQuery: strings.Repeat("a=1&", 10000) + "a=1",
|
||||
cleanQuery: "",
|
||||
}} {
|
||||
res, err := frontend.Client().Get(frontend.URL + "?" + test.rawQuery)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -956,6 +956,7 @@ func ParseQuery(query string) (Values, error) {
|
|||
|
||||
var urlmaxqueryparams = godebug.New("urlmaxqueryparams")
|
||||
|
||||
// Keep this in sync with net/http/httputil.
|
||||
const defaultMaxParams = 10000
|
||||
|
||||
func urlParamsWithinMax(params int) bool {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue