diff --git a/server/filesystem.go b/server/filesystem.go index d8499b0..e8720f2 100644 --- a/server/filesystem.go +++ b/server/filesystem.go @@ -71,7 +71,10 @@ func (fs FileSystem) newFile(name string) (*File, error) { return nil, err } if !fs.AllowOutsideSymlinks { - if target, _ := os.Readlink(absPath); target != "" { + if target, err := filepath.EvalSymlinks(absPath); target != "" { + if err != nil { + return nil, err + } path, err := filepath.Abs(target) if err != nil { return nil, err diff --git a/server/filesystem_test.go b/server/filesystem_test.go index 6fa0585..4932ab9 100644 --- a/server/filesystem_test.go +++ b/server/filesystem_test.go @@ -102,7 +102,7 @@ func (s *FileSystemTestSuite) TestNoLookupWithHTMLSuffix() { func (s *FileSystemTestSuite) TestNoOutsideSymlink() { s.WriteFile("foo", "content") root := s.Mkdir("root") - s.Symlink("foo", "root/foo-link") + s.Symlink("../foo", "root/foo-link") fs := server.FileSystem{Root: root} file, err := fs.Open("/foo-link") s.IsType(os.ErrPermission, err) @@ -113,13 +113,24 @@ func (s *FileSystemTestSuite) TestNoOutsideSymlink() { func (s *FileSystemTestSuite) TestOutsideSymlinks() { s.WriteFile("foo", "content") root := s.Mkdir("root") - s.Symlink("foo", "root/foo-link") + s.Symlink("../foo", "root/foo-link") fs := server.FileSystem{Root: root, AllowOutsideSymlinks: true} file, err := fs.Open("/foo-link") s.Nil(err) s.Equal("content", s.readFile(file)) } +// Local symlinks are always accessible. +func (s *FileSystemTestSuite) TestLocalSymlinks() { + root := s.Mkdir("root") + s.WriteFile("root/foo", "content") + s.Symlink("foo", "root/foo-link") + fs := server.FileSystem{Root: root} + file, err := fs.Open("/foo-link") + s.Nil(err) + s.Equal("content", s.readFile(file)) +} + // Files starting with a dot can be hidden. func (s *FileSystemTestSuite) TestHideDotFiles() { s.WriteFile(".foo", "") diff --git a/server/server_test.go b/server/server_test.go index a44d1d3..2a496d4 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -186,7 +186,7 @@ func (s *StaticServerTestSuite) TestSetupServerSpecifyAllowOutsideSymlinks() { content := "some content" s.WriteFile("outside.txt", content) subdir := s.Mkdir("sub") - s.Symlink("outside.txt", "sub/test.txt") + s.Symlink("../outside.txt", "sub/test.txt") serv, err := server.NewStaticServer(server.StaticServerConfig{ Dir: subdir, AllowOutsideSymlinks: true, diff --git a/testhelpers/tempdir.go b/testhelpers/tempdir.go index 2bc2044..c9c66f3 100644 --- a/testhelpers/tempdir.go +++ b/testhelpers/tempdir.go @@ -55,9 +55,8 @@ func (s *TempDirTestSuite) Mkdir(name string) string { // Symlink creates a symbolic link to oldname returning the absolute path of // the new name. Both paths are relative to the tempdir path. func (s *TempDirTestSuite) Symlink(oldname, newname string) string { - oldPath := s.absPath(oldname) newPath := s.absPath(newname) - err := os.Symlink(oldPath, newPath) + err := os.Symlink(oldname, newPath) s.Nil(err) return newPath }