Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net/http: ServerMux does not sanitize ".%2e" ("..") from url path #70130

Closed
WestleyK opened this issue Oct 30, 2024 · 4 comments
Closed

net/http: ServerMux does not sanitize ".%2e" ("..") from url path #70130

WestleyK opened this issue Oct 30, 2024 · 4 comments

Comments

@WestleyK
Copy link

Go version

go1.22.6 linux/amd64

Output of go env in your module/workspace:

GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/home/westley/.cache/go-build'
GOENV='/home/westley/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/westley/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/westley/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.22.6'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='<redacted>/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build1640283443=/tmp/go-build -gno-record-gcc-switches'

What did you do?

The http server mux implies it does request path sanitization, and it does work with .. in the url path, however, it does not work with .%2e.

Start a basic http server, go run main.go

Basic http server code
package main

import (
	"fmt"
	"log"
	"net/http"
)

func main() {
	mux := http.NewServeMux()

	mux.HandleFunc("/example/{paths...}", func(w http.ResponseWriter, r *http.Request) {
		fmt.Println("URL:", r.URL.Path)
		fmt.Println("Paths:", r.PathValue("paths"))
	})

	server := http.Server{
		Handler: mux,
		Addr:    ":8000",
	}

	log.Fatal(server.ListenAndServe())
}

What did you see happen?

The http server mux does not sanitize a path with url encoded ..

Tested with .. (expected)

$ curl -v --path-as-is localhost:8000/example/foo/../../../etc/passwd
* Uses proxy env variable no_proxy == 'localhost,127.0.0.0/8,::1'
*   Trying 127.0.0.1:8000...
* Connected to localhost (127.0.0.1) port 8000 (#0)
> GET /example/foo/../../../etc/passwd HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/7.81.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 301 Moved Permanently
< Content-Type: text/html; charset=utf-8
< Location: /etc/passwd
< Date: Wed, 30 Oct 2024 21:19:39 GMT
< Content-Length: 46
< 
<a href="/etc/passwd">Moved Permanently</a>.

* Connection #0 to host localhost left intact

Tested with .%2e (possible security issue, does not get sanitized)

$ curl -v --path-as-is localhost:8000/example/foo/.%2e/.%2e/.%2e/etc/passwd
* Uses proxy env variable no_proxy == 'localhost,127.0.0.0/8,::1'
*   Trying 127.0.0.1:8000...
* Connected to localhost (127.0.0.1) port 8000 (#0)
> GET /example/foo/.%2e/.%2e/.%2e/etc/passwd HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/7.81.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Wed, 30 Oct 2024 21:19:54 GMT
< Content-Length: 0
< 
* Connection #0 to host localhost left intact

Output from the server:

URL: /example/foo/../../../etc/passwd
Paths: foo/../../../etc/passwd

What did you expect to see?

I expected http server mux to sanitize the url encoded ., and reject the request before it gets to the handler.

@seankhliao
Copy link
Member

The current behaviour is consistent with #21955 where we chose to preserve the path if it is escaped.

@seankhliao seankhliao closed this as not planned Won't fix, can't repro, duplicate, stale Oct 30, 2024
@WestleyK
Copy link
Author

Makes sense, perhaps that this should be documented somewhere, that ServerMux will not fully sanitize the path, as it might imply; "ServeMux also takes care of sanitizing the URL request path".

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/623835 mentions this issue: net/http: clarify ServeMux path sanitization

gopherbot pushed a commit that referenced this issue Oct 31, 2024
For #70130

Change-Id: Idd7ca3d11b78887709b83dd5c868de9cc506ecff
Reviewed-on: https://go-review.googlesource.com/c/go/+/623835
Reviewed-by: Carlos Amedee <carlos@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants