fix: Ensure requested file from server is within a base path (#5564)

Signed-off-by: jannfis <jann@mistrust.net>
This commit is contained in:
jannfis 2021-03-02 22:32:12 +01:00 committed by GitHub
parent e33330fce1
commit 5fa10a3526
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 36 additions and 3 deletions

View file

@ -12,6 +12,7 @@ import (
"os"
"os/exec"
"path"
"path/filepath"
"regexp"
"strings"
"time"
@ -825,8 +826,18 @@ func indexFilePath(srcPath string, baseHRef string) (string, error) {
return filePath, nil
}
func fileExists(filename string) bool {
info, err := os.Stat(filename)
func fileExists(dir, filename string) bool {
// We make sure that the resulting path is within the directory we intend to
// serve content from. path.Join() will normalize the path.
abs, err := filepath.Abs(dir)
if err != nil {
return false
}
fp := path.Join(abs, filename)
if !strings.HasPrefix(fp, abs) {
return false
}
info, err := os.Stat(fp)
if os.IsNotExist(err) {
return false
}
@ -843,7 +854,8 @@ func (server *ArgoCDServer) newStaticAssetsHandler(dir string, baseHRef string)
break
}
}
fileRequest := r.URL.Path != "/index.html" && fileExists(path.Join(dir, r.URL.Path))
fileRequest := r.URL.Path != "/index.html" && fileExists(dir, r.URL.Path)
// Set X-Frame-Options according to configuration
if server.XFrameOptions != "" {

View file

@ -546,3 +546,24 @@ func TestInitializeDefaultProject_ProjectAlreadyInitialized(t *testing.T) {
assert.Equal(t, proj.Spec, existingDefaultProject.Spec)
}
func TestFileExists(t *testing.T) {
t.Run("File exists and path is within dir", func(t *testing.T) {
exists := fileExists(".", "server.go")
assert.True(t, exists)
exists = fileExists(".", "account/account.go")
assert.True(t, exists)
})
t.Run("File does not exist", func(t *testing.T) {
exists := fileExists(".", "notexist.go")
assert.False(t, exists)
})
t.Run("Dir does not exist", func(t *testing.T) {
exists := fileExists("/notexisting", "server.go")
assert.False(t, exists)
})
t.Run("File outside of dir", func(t *testing.T) {
exists := fileExists(".", "../reposerver/server.go")
assert.False(t, exists)
})
}