Does Go sanitize URLs for web requests?

go, web

Solution

`net/http` does this in its HTTP request multiplexer, `ServeMux`:

ServeMux also takes care of sanitizing the URL request path, redirecting any request containing . or .. elements to an equivalent .- and ..-free URL.

The relevant function is the private func `cleanPath(p string) string`, which calls `path.Clean`:

1415        np := path.Clean(p)

`path.Clean` does the appropriate removals:

 97         case path[r] == '.' && path[r+1] == '.' && (r+2 == n || path[r+2] == '/'):
 98             // .. element: remove to last /
 99             r += 2
100             switch {
101             case out.w > dotdot:
102                 // can backtrack
103                 out.w--
104                 for out.w > dotdot && out.index(out.w) != '/' {
105                     out.w--
106                 }

There's an additional case if the path isn't rooted, but `cleanPath` above ensures it is so, by prepending a forward-slash to the path to be cleaned if there isn't one already.

Problem

I was implementing a simple web server in Go. As I have no experience in web development, this striked as a serious question for me. Let's say I'm serving web pages with a modified `loadPage` function from here ``` func loadPage(title string) []byte { filename := title body, _ := ioutil.ReadFile(filename) return body } func handler(w http.ResponseWriter, req *http.Request) { content := loadPage(req.URL.Path[1:]) fmt.Fprintf(w, "%s", content) } ``` Technically this allows me to write a request in a form of ``` http://example.com/../../etc/passwd ``` and the code would happily serve the /etc/passwd file, but it does not. Does this mean that there is some sort of protection against `../` in the Go http package or http protocol itself, or am I just doing something wrong and it is a security hole?

Original source