Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Go sanitize URLs for web requests?

Tags:

go

web

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?

like image 887
UldisK Avatar asked Apr 25 '14 06:04

UldisK


1 Answers

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.

like image 79
Asherah Avatar answered Nov 05 '22 02:11

Asherah