Reject requests containing '..' in them

This commit is contained in:
adnano 2020-09-26 17:13:13 -04:00
parent ceb40a2fab
commit a1a2523c5c

View File

@ -264,6 +264,7 @@ type ServeDir struct {
} }
// FileServer takes a filesystem and returns a handler which uses that filesystem. // 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 { func FileServer(fsys FS) Handler {
return fsHandler{ return fsHandler{
fsys, fsys,
@ -275,6 +276,12 @@ type fsHandler struct {
} }
func (fsys fsHandler) Serve(rw *ResponseWriter, req *Request) { 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 // FIXME: Don't serve paths with .. in them
f, err := fsys.Open(req.URL.Path) f, err := fsys.Open(req.URL.Path)
if err != nil { if err != nil {
@ -288,6 +295,20 @@ func (fsys fsHandler) Serve(rw *ResponseWriter, req *Request) {
io.Copy(rw, f) 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 // TODO: replace with fs.FS when available
type FS interface { type FS interface {
Open(name string) (File, error) Open(name string) (File, error)