mirror of
https://github.com/drakkan/sftpgo.git
synced 2025-12-07 14:50:55 +03:00
pattern filters: don't allow files in hidden dirs
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
@@ -496,15 +496,19 @@ func TestHiddenPatternFilter(t *testing.T) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
dirName := "beta"
|
dirName := "beta"
|
||||||
|
subDirName := "testDir"
|
||||||
testFile := filepath.Join(u.GetHomeDir(), deniedDir, "file.txt")
|
testFile := filepath.Join(u.GetHomeDir(), deniedDir, "file.txt")
|
||||||
testFile1 := filepath.Join(u.GetHomeDir(), deniedDir, "beta.txt")
|
testFile1 := filepath.Join(u.GetHomeDir(), deniedDir, "beta.txt")
|
||||||
|
testHiddenFile := filepath.Join(u.GetHomeDir(), deniedDir, dirName, subDirName, "hidden.jpg")
|
||||||
err = os.MkdirAll(filepath.Join(u.GetHomeDir(), deniedDir), os.ModePerm)
|
err = os.MkdirAll(filepath.Join(u.GetHomeDir(), deniedDir), os.ModePerm)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
err = os.WriteFile(testFile, testFileContent, os.ModePerm)
|
err = os.WriteFile(testFile, testFileContent, os.ModePerm)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
err = os.WriteFile(testFile1, testFileContent, os.ModePerm)
|
err = os.WriteFile(testFile1, testFileContent, os.ModePerm)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
err = os.MkdirAll(filepath.Join(u.GetHomeDir(), deniedDir, dirName), os.ModePerm)
|
err = os.MkdirAll(filepath.Join(u.GetHomeDir(), deniedDir, dirName, subDirName), os.ModePerm)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
err = os.WriteFile(testHiddenFile, testFileContent, os.ModePerm)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
conn, client, err := getSftpClient(user)
|
conn, client, err := getSftpClient(user)
|
||||||
@@ -529,6 +533,10 @@ func TestHiddenPatternFilter(t *testing.T) {
|
|||||||
assert.ErrorIs(t, err, os.ErrPermission)
|
assert.ErrorIs(t, err, os.ErrPermission)
|
||||||
err = writeSFTPFile(path.Join(deniedDir, "afile.txt"), 1024, client)
|
err = writeSFTPFile(path.Join(deniedDir, "afile.txt"), 1024, client)
|
||||||
assert.ErrorIs(t, err, os.ErrPermission)
|
assert.ErrorIs(t, err, os.ErrPermission)
|
||||||
|
err = writeSFTPFile(path.Join(deniedDir, dirName, subDirName, "afile.jpg"), 1024, client)
|
||||||
|
assert.ErrorIs(t, err, os.ErrPermission)
|
||||||
|
_, err = client.Open(path.Join(deniedDir, dirName, subDirName, filepath.Base(testHiddenFile)))
|
||||||
|
assert.ErrorIs(t, err, os.ErrNotExist)
|
||||||
err = client.Symlink(path.Join(deniedDir, dirName), dirName)
|
err = client.Symlink(path.Join(deniedDir, dirName), dirName)
|
||||||
assert.ErrorIs(t, err, os.ErrNotExist)
|
assert.ErrorIs(t, err, os.ErrNotExist)
|
||||||
err = writeSFTPFile(path.Join(deniedDir, testFileName), 1024, client)
|
err = writeSFTPFile(path.Join(deniedDir, testFileName), 1024, client)
|
||||||
@@ -568,6 +576,12 @@ func TestHiddenPatternFilter(t *testing.T) {
|
|||||||
assert.ErrorIs(t, err, os.ErrPermission)
|
assert.ErrorIs(t, err, os.ErrPermission)
|
||||||
err = client.Symlink(path.Join(deniedDir, testFileName), path.Join(deniedDir, "link.txt"))
|
err = client.Symlink(path.Join(deniedDir, testFileName), path.Join(deniedDir, "link.txt"))
|
||||||
assert.ErrorIs(t, err, os.ErrPermission)
|
assert.ErrorIs(t, err, os.ErrPermission)
|
||||||
|
err = writeSFTPFile(path.Join(deniedDir, dirName, subDirName, "afile.jpg"), 1024, client)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
f, err := client.Open(path.Join(deniedDir, dirName, subDirName, filepath.Base(testHiddenFile)))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
err = f.Close()
|
||||||
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = httpdtest.RemoveUser(user, http.StatusOK)
|
_, err = httpdtest.RemoveUser(user, http.StatusOK)
|
||||||
|
|||||||
@@ -854,10 +854,32 @@ func (u *User) getPatternsFilterForPath(virtualPath string) sdk.PatternsFilter {
|
|||||||
return filter
|
return filter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *User) isDirHidden(virtualPath string) bool {
|
||||||
|
if len(u.Filters.FilePatterns) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for _, dirPath := range util.GetDirsForVirtualPath(virtualPath) {
|
||||||
|
if dirPath == "/" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
filter := u.getPatternsFilterForPath(dirPath)
|
||||||
|
if filter.DenyPolicy == sdk.DenyPolicyHide {
|
||||||
|
if !filter.CheckAllowed(path.Base(dirPath)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// IsFileAllowed returns true if the specified file is allowed by the file restrictions filters.
|
// IsFileAllowed returns true if the specified file is allowed by the file restrictions filters.
|
||||||
// The second parameter returned is the deny policy
|
// The second parameter returned is the deny policy
|
||||||
func (u *User) IsFileAllowed(virtualPath string) (bool, int) {
|
func (u *User) IsFileAllowed(virtualPath string) (bool, int) {
|
||||||
filter := u.getPatternsFilterForPath(path.Dir(virtualPath))
|
dirPath := path.Dir(virtualPath)
|
||||||
|
if u.isDirHidden(dirPath) {
|
||||||
|
return false, sdk.DenyPolicyHide
|
||||||
|
}
|
||||||
|
filter := u.getPatternsFilterForPath(dirPath)
|
||||||
return filter.CheckAllowed(path.Base(virtualPath)), filter.DenyPolicy
|
return filter.CheckAllowed(path.Base(virtualPath)), filter.DenyPolicy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user