From d88273ab55237aad4abb64eb2c5b200a36a3d4af Mon Sep 17 00:00:00 2001 From: "Gerasimos (Makis) Maropoulos" Date: Wed, 24 Apr 2024 18:25:24 +0300 Subject: [PATCH] minor --- aliases.go | 7 +++---- context/context.go | 25 ++++++++++++++----------- context/fs.go | 14 +++++++++++--- 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/aliases.go b/aliases.go index 38d60b2a..dcedfd11 100644 --- a/aliases.go +++ b/aliases.go @@ -4,7 +4,6 @@ import ( "io/fs" "net/http" "net/url" - "path" "regexp" "strings" "time" @@ -326,7 +325,7 @@ type prefixedDir struct { } func (p *prefixedDir) Open(name string) (http.File, error) { - destPath, filename, ok, err := context.SafeFilename(p.prefix, name) + destPath, _, ok, err := context.SafeFilename(p.prefix, name) if err != nil { return nil, err } @@ -334,8 +333,8 @@ func (p *prefixedDir) Open(name string) (http.File, error) { return nil, http.ErrMissingFile // unsafe. } - name = path.Join(destPath, filename) - return p.fs.Open(name) + // name = path.Join(destPath, filename) + return p.fs.Open(destPath) } type partyConfiguratorMiddleware struct { diff --git a/context/context.go b/context/context.go index 3a254fb1..0a57a679 100644 --- a/context/context.go +++ b/context/context.go @@ -2418,19 +2418,22 @@ func SafeFilename(prefixDir string, name string) (string, string, bool, error) { return prefixDir, name, false, nil } - // Join the sanitized input with the destination directory. - destPath := filepath.Join(prefixDir, filename) + var destPath string + if prefixDir != "" { + // Join the sanitized input with the destination directory. + destPath = filepath.Join(prefixDir, filename) - // Get the canonical path of the destination directory. - canonicalDestDir, err := filepath.EvalSymlinks(prefixDir) // the prefix dir should exists. - if err != nil { - return prefixDir, name, false, fmt.Errorf("dest directory: %s: eval symlinks: %w", prefixDir, err) - } + // Get the canonical path of the destination directory. + canonicalDestDir, err := filepath.EvalSymlinks(prefixDir) // the prefix dir should exists. + if err != nil { + return prefixDir, name, false, fmt.Errorf("dest directory: %s: eval symlinks: %w", prefixDir, err) + } - // Check if the destination path is within the destination directory. - if !strings.HasPrefix(destPath, canonicalDestDir) { - // Reject the input as it is a path traversal attempt. - return prefixDir, name, false, nil + // Check if the destination path is within the destination directory. + if !strings.HasPrefix(destPath, canonicalDestDir) { + // Reject the input as it is a path traversal attempt. + return prefixDir, name, false, nil + } } return destPath, filename, true, nil diff --git a/context/fs.go b/context/fs.go index 8ff8164a..d7d1d4b3 100644 --- a/context/fs.go +++ b/context/fs.go @@ -134,7 +134,15 @@ var ResolveHTTPFS = func(fsOrDir interface{}) http.FileSystem { // FindNames accepts a "http.FileSystem" and a root name and returns // the list containing its file names. func FindNames(fileSystem http.FileSystem, name string) ([]string, error) { - f, err := fileSystem.Open(name) + _, filename, ok, err := SafeFilename("", name) + if err != nil { + return nil, err + } + if !ok { + return nil, fmt.Errorf("invalid file name: %s", name) + } + + f, err := fileSystem.Open(filename) if err != nil { return nil, err } @@ -160,8 +168,8 @@ func FindNames(fileSystem http.FileSystem, name string) ([]string, error) { // Note: // go-bindata has absolute names with os.Separator, // http.Dir the basename. - filename := toBaseName(info.Name()) - fullname := path.Join(name, filename) + baseFilename := toBaseName(info.Name()) + fullname := path.Join(name, baseFilename) if fullname == name { // prevent looping through itself. continue }