github.com/argoproj/argo-cd/v3@v3.2.1/util/security/path_traversal.go (about) 1 package security 2 3 import ( 4 "fmt" 5 "path/filepath" 6 "strings" 7 ) 8 9 // Ensure that `requestedPath` is on the same directory or any subdirectory of `currentRoot`. Both `currentRoot` and 10 // `requestedPath` must be absolute paths. They may contain any number of `./` or `/../` dir changes. 11 func EnforceToCurrentRoot(currentRoot, requestedPath string) (string, error) { 12 currentRoot = filepath.Clean(currentRoot) 13 requestedDir, requestedFile := parsePath(requestedPath) 14 if !isRequestedDirUnderCurrentRoot(currentRoot, requestedDir) { 15 return "", fmt.Errorf("requested path %s should be on or under current directory %s", requestedPath, currentRoot) 16 } 17 return requestedDir + string(filepath.Separator) + requestedFile, nil 18 } 19 20 func isRequestedDirUnderCurrentRoot(currentRoot, requestedPath string) bool { 21 if currentRoot == string(filepath.Separator) { 22 return true 23 } else if currentRoot == requestedPath { 24 return true 25 } 26 if requestedPath[len(requestedPath)-1] != '/' { 27 requestedPath = requestedPath + "/" 28 } 29 if currentRoot[len(currentRoot)-1] != '/' { 30 currentRoot = currentRoot + "/" 31 } 32 return strings.HasPrefix(requestedPath, currentRoot) 33 } 34 35 func parsePath(path string) (string, string) { 36 directory := filepath.Dir(path) 37 if directory == path { 38 return directory, "" 39 } 40 return directory, filepath.Base(path) 41 }