From a1a2523c5c1981c2f5494d3e44f5c1dcf681209a Mon Sep 17 00:00:00 2001 From: adnano Date: Sat, 26 Sep 2020 17:13:13 -0400 Subject: [PATCH] Reject requests containing '..' in them --- server.go | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/server.go b/server.go index 480eb48..96747e1 100644 --- a/server.go +++ b/server.go @@ -264,6 +264,7 @@ type ServeDir struct { } // FileServer takes a filesystem and returns a handler which uses that filesystem. +// The returned Handler rejects requests containing '..' in them. func FileServer(fsys FS) Handler { return fsHandler{ fsys, @@ -275,6 +276,12 @@ type fsHandler struct { } func (fsys fsHandler) Serve(rw *ResponseWriter, req *Request) { + if containsDotDot(req.URL.Path) { + // Reject requests with '..' in them + rw.WriteHeader(StatusBadRequest, "Invalid URL path") + return + } + // FIXME: Don't serve paths with .. in them f, err := fsys.Open(req.URL.Path) if err != nil { @@ -288,6 +295,20 @@ func (fsys fsHandler) Serve(rw *ResponseWriter, req *Request) { io.Copy(rw, f) } +func containsDotDot(v string) bool { + if !strings.Contains(v, "..") { + return false + } + for _, ent := range strings.FieldsFunc(v, isSlashRune) { + if ent == ".." { + return true + } + } + return false +} + +func isSlashRune(r rune) bool { return r == '/' || r == '\\' } + // TODO: replace with fs.FS when available type FS interface { Open(name string) (File, error)